Skip to content

Commit

Permalink
feat: Allow including Access Lists as nested members and owners
Browse files Browse the repository at this point in the history
- Recursively check for accesslist membership

- Allow adding/removing/listing included access lists in acl commands

- Add a recursive test

- Use dynamic access lists structure from RFD

- Resolve proto changes

- Exclude 'list' members from Access List memberCount

- Calc Access List member count with members of type 'list' excluded,
  return seperately to front end

- Update examples/integrations

- Update crd docs

- Update tf docs

- Perform calculation of inherited roles/traits to AccessList service in
  order to utilize cache and minimize number of requests.

- Grant Okta integration RO for Access Lists

- Update AccessListMember-* events

- Include count for inherited grants

- Include MembershipKind of affected member(s)

- Emit inherited grants / members' MembershipKind for AccessListMember-*
  events

- Update notified owners for Access Requests

- Ensure dynamic owners are notified for Access Requests

- Ensure dynamic owners are notified via Slack integration

- Add `accesslistconv.{ToOwnerProto/FromOwnerProto}` for convenience

- Optionally pass an AbortSignal to `fetchAccessLists` in Web UI

chore: Consolidate common nested Access List funcs

- Move common nested-AccessList-related funcs to
  lib/accesslists/hierarchy

- Modify Grant inheritance so Members in lists added as Owners inherit
  Ownership and OwnerGrants, instead of just Ownership

- Update UserLoginStateGenerator to reflect this change in Grant
  inheritance, and to not store inherited grants on `state` object

- Don't check membership/ownership of AccessList while User is locked

- Replace usages of `services.IsAccessListOwner` with `Hierarchy`

- Replace usages of `services.IsAccessListOwner/IsAccessListMember` with
  equivelant funcs from `Hierarchy`

- Remove final references to AccessListMembershipChecker

- Don't allow ACL deletion when member/owner in other lists

- Guard Access List deletion behind membership/ownership checks for List

- Expose Hierarchy func to recursively get all members

- Tidy UserLoginStateGenerator logic involving ACL Membership/Ownership
  • Loading branch information
kiosion committed Oct 17, 2024
1 parent cce1157 commit 446052d
Show file tree
Hide file tree
Showing 52 changed files with 7,447 additions and 4,142 deletions.
42 changes: 39 additions & 3 deletions api/client/accesslist/accesslist.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1"
"github.com/gravitational/teleport/api/types/accesslist"
conv "github.com/gravitational/teleport/api/types/accesslist/convert/v1"
traitv1 "github.com/gravitational/teleport/api/types/trait/convert/v1"
)

// Client is an access list client that conforms to the following lib/services interfaces:
Expand Down Expand Up @@ -113,6 +114,21 @@ func (c *Client) GetAccessListsToReview(ctx context.Context) ([]*accesslist.Acce
return accessLists, nil
}

// GetInheritedGrants returns grants inherited by access list accessListID from parent access lists.
func (c *Client) GetInheritedGrants(ctx context.Context, accessListID string) (*accesslist.Grants, error) {
resp, err := c.grpcClient.GetInheritedGrants(ctx, &accesslistv1.GetInheritedGrantsRequest{
AccessListId: accessListID,
})
if err != nil {
return nil, trace.Wrap(err)
}

return &accesslist.Grants{
Roles: resp.Grants.Roles,
Traits: traitv1.FromProto(resp.Grants.Traits),
}, nil
}

// UpsertAccessList creates or updates an access list resource.
func (c *Client) UpsertAccessList(ctx context.Context, accessList *accesslist.AccessList) (*accesslist.AccessList, error) {
resp, err := c.grpcClient.UpsertAccessList(ctx, &accesslistv1.UpsertAccessListRequest{
Expand Down Expand Up @@ -151,15 +167,15 @@ func (c *Client) DeleteAllAccessLists(ctx context.Context) error {
}

// CountAccessListMembers will count all access list members.
func (c *Client) CountAccessListMembers(ctx context.Context, accessListName string) (uint32, error) {
func (c *Client) CountAccessListMembers(ctx context.Context, accessListName string) (users uint32, lists uint32, err error) {
resp, err := c.grpcClient.CountAccessListMembers(ctx, &accesslistv1.CountAccessListMembersRequest{
AccessListName: accessListName,
})
if err != nil {
return 0, trace.Wrap(err)
return 0, 0, trace.Wrap(err)
}

return resp.Count, nil
return resp.Count, resp.ListCount, nil
}

// ListAccessListMembers returns a paginated list of all access list members for an access list.
Expand Down Expand Up @@ -221,6 +237,26 @@ func (c *Client) GetAccessListMember(ctx context.Context, accessList string, mem
return member, trace.Wrap(err)
}

// GetAccessListOwners returns a list of all owners in an Access List, including those inherited from nested Access Lists.
//
// Returned Owners are not validated for ownership requirements – use `IsAccessListOwner` for validation.
func (c *Client) GetAccessListOwners(ctx context.Context, accessListName string) ([]*accesslist.Owner, error) {
resp, err := c.grpcClient.GetAccessListOwners(ctx, &accesslistv1.GetAccessListOwnersRequest{
AccessList: accessListName,
})
if err != nil {
return nil, trace.Wrap(err)
}

owners := make([]*accesslist.Owner, 0, len(resp.Owners))
for _, owner := range resp.Owners {
ownerProto := conv.FromOwnerProto(owner)
owners = append(owners, &ownerProto)
}

return owners, nil
}

// UpsertAccessListMember creates or updates an access list member resource.
func (c *Client) UpsertAccessListMember(ctx context.Context, member *accesslist.AccessListMember) (*accesslist.AccessListMember, error) {
resp, err := c.grpcClient.UpsertAccessListMember(ctx, &accesslistv1.UpsertAccessListMemberRequest{
Expand Down
547 changes: 327 additions & 220 deletions api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go

Large diffs are not rendered by default.

Loading

0 comments on commit 446052d

Please sign in to comment.