Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,5 @@ require (
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.50.0 // indirect
)

replace github.com/conductorone/baton-sdk => ../baton-sdk-2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Security: This replace directive points the baton-sdk at an unpublished local filesystem path (../baton-sdk-2), and go.sum drops the baton-sdk v0.18.2 checksums accordingly. The connector cannot be reproducibly built by anyone without that sibling directory, and the entire new feature depends on unreleased SDK types (TypeScopedGrants, SourceCache*, SpawnCursors, TypeScopedGrantsSyncer, the sourcecache package). Before merging to main, cut a tagged SDK release and pin a real version, removing the local replace and restoring go.sum.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Security: This replace points the SDK at a local sibling directory (../baton-sdk-2), an unpublished fork. The build is unreproducible for anyone (CI included) without that path, and go.sum dropping the v0.18.2 checksum means the pinned SDK no longer resolves. This must be replaced with a real released SDK version before merging to main; the entire feature depends on SDK APIs (TypeScopedGrantsSyncer, sourcecache, SpawnCursors, SourceCacheReplay) that only exist in this local fork. (confidence: high)

2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ github.com/cockroachdb/swiss v0.0.0-20251224182025-b0f6560f979b h1:VXvSNzmr8hMj8
github.com/cockroachdb/swiss v0.0.0-20251224182025-b0f6560f979b/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/conductorone/baton-sdk v0.18.2 h1:2pFlzwSpaFnIv0GbmTmLtIUOqWuNBtlsm28mujt7F5g=
github.com/conductorone/baton-sdk v0.18.2/go.mod h1:xacgmef9cM4dUTdvGN3Qip6fwkRbciqtaZMi5iWnjsY=
github.com/conductorone/dpop v0.2.6 h1:fakwai/Xm2b/fcDUwJN41WtcSI/2UhQOyRIVvnnrrNA=
github.com/conductorone/dpop v0.2.6/go.mod h1:gyo8TtzB9SCFCsjsICH4IaLZ7y64CcrDXMOPBwfq/3s=
github.com/conductorone/dpop/integrations/dpop_grpc v0.2.4 h1:lYxYi9/WTSL9sE96CO0QF2BY3kehs8dTTApI134TGCA=
Expand Down
29 changes: 26 additions & 3 deletions pkg/connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ func capabilityPermissions(perms ...string) *v2.CapabilityPermissions {
return cp
}

func groupResourceTypeAnnotations() annotations.Annotations {
annos := v1AnnotationsForResourceType("group", false, capabilityPermissions("okta.groups.read", "okta.groups.manage"))
annos.Update(&v2.TypeScopedGrants{})
return annos
}

func v1AnnotationsForResourceType(resourceTypeID string, skipEntitlementsAndGrants bool, perms *v2.CapabilityPermissions) annotations.Annotations {
annos := annotations.Annotations{}
annos.Update(&v2.V1Identifier{
Expand Down Expand Up @@ -88,11 +94,15 @@ var (
Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_USER},
Annotations: v1AnnotationsForResourceType(userResourceTypeID, true, capabilityPermissions("okta.users.read", "okta.users.manage")),
}
// TypeScopedGrants excludes the group type from the SDK's per-resource
// grants fan-out: full syncs enumerate group grants through the
// planner/cursors in group_type_scoped.go (with source-cache replay for
// clean groups); the per-resource path serves targeted syncs.
resourceTypeGroup = &v2.ResourceType{
Id: "group",
DisplayName: "Group",
Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_GROUP},
Annotations: v1AnnotationsForResourceType("group", false, capabilityPermissions("okta.groups.read", "okta.groups.manage")),
Annotations: groupResourceTypeAnnotations(),
}
resourceTypeApp = &v2.ResourceType{
Id: "app",
Expand Down Expand Up @@ -275,8 +285,14 @@ func (c *Okta) Metadata(ctx context.Context) (*v2.ConnectorMetadata, error) {
}

func (c *Okta) Validate(ctx context.Context) (annotations.Annotations, error) {
// Source-cache replay opt-in: group member grants are validated by
// lastMembershipUpdated (group_type_scoped.go).
annos := annotations.New(&v2.SourceCacheCapability{
Mode: v2.SourceCacheCapability_MODE_READ_WRITE,
})

if c.apiToken == "" {
return nil, nil
return annos, nil
}

token := newPaginationToken(defaultLimit, "")
Expand All @@ -296,7 +312,7 @@ func (c *Okta) Validate(ctx context.Context) (annotations.Annotations, error) {
return nil, err
}

return nil, nil
return annos, nil
}

func (c *Okta) Asset(ctx context.Context, asset *v2.AssetRef) (string, io.ReadCloser, error) {
Expand All @@ -320,6 +336,13 @@ func New(ctx context.Context, cc *cfg.Okta, opts *cli.ConnectorOpts) (connectorb
return nil, nil, err
}

// Demo instrumentation: count/log Okta requests when
// BATON_OKTA_REQUEST_LOG is set (source-cache measurement harness).
client, err = wrapRequestCounting(client)
if err != nil {
return nil, nil, err
}

cacheTTI, err := safeCacheInt32(cc.CacheTti)
if err != nil {
return nil, nil, err
Expand Down
6 changes: 5 additions & 1 deletion pkg/connector/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const appGroupType = "APP_GROUP"
const oktaGroupType = "OKTA_GROUP"
const apiPathGetGroupFmt = "/api/v1/groups/%s"

// groupRoleAssignmentType is the assignmentType value on role assignments
// held by a group (vs "USER").
const groupRoleAssignmentType = "GROUP"

type groupResourceType struct {
resourceType *v2.ResourceType
connector *Okta
Expand Down Expand Up @@ -209,7 +213,7 @@ func (o *groupResourceType) Grants(
}

for _, role := range roles {
if role.Status == roleStatusInactive || role.AssignmentType != "GROUP" {
if role.Status == roleStatusInactive || role.AssignmentType != groupRoleAssignmentType {
continue
}

Expand Down
Loading
Loading