Skip to content

[CXH-389, CXH-903] - Sync group descriptions to resources and membership entitlements - Okta Connector - #199

Merged
mateoHernandez123 merged 3 commits into
mainfrom
mateoHernandez123/okta-group-description-entitlements
Aug 26, 2026
Merged

[CXH-389, CXH-903] - Sync group descriptions to resources and membership entitlements - Okta Connector#199
mateoHernandez123 merged 3 commits into
mainfrom
mateoHernandez123/okta-group-description-entitlements

Conversation

@mateoHernandez123

Copy link
Copy Markdown
Contributor

Description

  • Bug fix
  • New feature

Okta group descriptions were being synced into the group profile map but never onto the resource itself, and the membership entitlement always used a generated Member of <group> group in Okta template. That template is what ConductorOne shows on access-request forms, in access reviews and in CSV exports, so the guidance admins write in Okta never reached the people who needed it.

This makes the connector use the group's real Okta description in both places: on Resource.Description for the group resource, and as the member entitlement's description. Groups with no description in Okta keep the generated template, so nothing regresses for tenants that never filled the field in.

CXH-389 (Allvue, DoorDash) is the entitlement half — the description shown on the request form. CXH-903 (PsiQuantum) is the resource half — they run several groups with the same name and the description is the only thing that tells them apart. They are the same change: following the pattern Active Directory shipped in CXH-1157, the entitlement reads resource.Description, so the resource has to carry it first.

Sync:

  • Groups (group) — the resource now carries the Okta group description, and the member entitlement uses it instead of the generated template. Whitespace-only descriptions are treated as unset and fall back to the template.
  • Users (user) — unchanged surface
  • Roles (role) — unchanged surface
  • Apps (app) — unchanged surface
  • Resource sets (resource_sets) — unchanged surface (see Architecture highlights for why)

Provisioning:

unchanged

Auth:

unchanged — no new config flag, no new scope or permission. The group description is already returned by the same GET /api/v1/groups call the connector makes today (GroupProfile.Description in the vendored Okta SDK), so this adds no API calls.

Architecture highlights:

  • No entitlement re-keying. The entitlement ID stays group:<okta-group-id>:member — the SDK derives it from the resource ID and the slug, not the description — and the slug and display name are unchanged. Existing grants keep pointing at the same entitlement. A unit test pins all three so a future change cannot drift.
  • Descriptions are clamped to 2048 bytes on a character boundary. The connector protocol caps Resource.Description and Entitlement.Description at 2048 bytes and enforces it through the gRPC validation interceptor. Okta caps group descriptions at 1024 UTF-16 units, not bytes, so a 1024-character CJK description is accepted by Okta at 3072 bytes of UTF-8. Without the clamp a single such group aborts the entire sync with InvalidArgument: value length must be between 1 and 2048 bytes. The clamp backs off to the last complete character so the value stays valid UTF-8.
  • The profile description key is left carrying Okta's raw value. That key is an already-shipped contract, so the trim and the clamp apply only to the new resource-level description; a test asserts the profile still holds the untouched Okta string.
  • Scope: groups only, and baton-okta only. Okta resource sets have the same gap (description synced to the profile but not to the resource, entitlement on a template) and roles do not carry the description at all even though the API exposes it. Both are deliberately left out — CXH-389 and CXH-903 are both about groups, and roles would need a new profile key. Worth a follow-up rather than widening an urgent fix. On the connector axis: CXH-389's title mentions CIAM, but baton-okta-ciam registers no group syncer and never emits a group entitlement, so it cannot show this. (baton-okta-ciam-workforce is a different catalog product that does carry the same template; nobody has reported it and it is not named in the ticket. Reasoning is written up on CXH-389.)
  • Known platform-side limit, worth knowing before testing this. C1 takes the entitlement description when the entitlement is first created and then freezes it via user_edited_mask; on a later sync a differing connector description sets the mask instead of updating the field. So on a tenant whose group entitlements already exist, this change will not rewrite them — newly created entitlements get the real description. The resource description has no such limit and updates on every sync. Validated against a live Okta tenant and a full C1 stack, including an A/B between this branch and main on the same tenant.

Useful links:

…t descriptions

The Okta group description was only written into the group profile map, so
the group resource carried no description and the membership entitlement
always used a generated "Member of <group> group in Okta" template. C1
surfaces the entitlement description on access-request forms, in access
reviews and in CSV exports, so the guidance admins write in Okta never
reached the people deciding on the request.

Set the description on the group resource and reuse it for the member
entitlement, falling back to the generated text when the group has none.

Descriptions are clamped to the protocol's 2048-byte budget on a character
boundary: Okta caps group descriptions at 1024 UTF-16 units, which is up to
3072 bytes of UTF-8, and an over-long value fails validation and aborts the
whole sync. The profile key keeps carrying Okta's raw value, since that is
an already-shipped contract.

The entitlement id, slug and display name are unchanged, so no existing
grant is re-keyed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

CXH-389

CXH-903

Comment thread pkg/connector/group.go
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: [CXH-389, CXH-903] - Sync group descriptions to resources and membership entitlements - Okta Connector

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 8ffb5fe10168.
Review mode: full
View review run

Review Summary

Scanned the full PR diff (pkg/connector/group.go, pkg/connector/group_test.go — no manifest, config, or docs changes) for security and correctness. The change sets Resource.Description from the Okta group description and reuses it for the member entitlement with a fallback to the existing generated template; entitlement id, slug, and display name are unchanged, so no grants are re-keyed. Prior bot feedback is addressed: the truncation is now observable via the Debug line in List (the Warn escalation was declined by the author and a maintainer, so it is not re-raised), and 7dd3326c removed the redundant per-group TrimSpace by gating on the raw length — which is safe, since trimming can only shorten and therefore produces no false negatives. No new issues found.

Verified specifically: the clamp backs off to a character boundary and cannot loop past an empty string; group.Profile is already dereferenced by groupProfileMap on the same path, so line 93 adds no new nil surface; whitespace-only descriptions collapse to empty so the entitlement keeps its non-empty template; the profile description key still carries Okta's raw value; and the clamp is inherited by the entitlement because it reads the already-clamped resource description.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot left a comment

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.

No blocking issues found.

… budget

An over-budget description was clamped silently, so a description that
renders cut off in ConductorOne could not be confirmed from a sync log.

The log lives in List rather than in groupDescription so the mapping helper
stays pure and no call site changes signature, matching how the rest of the
connector logs skip and mapping decisions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread pkg/connector/group.go Outdated

@github-actions github-actions Bot left a comment

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.

No blocking issues found.

Comment thread pkg/connector/group.go Outdated
The log check trimmed the description again even though groupDescription
already trimmed it while building the resource, so every group paid for a
second TrimSpace during sync.

Trimming only ever shortens, so the raw length now gates the check and the
trim happens only for a description that is actually over budget. Comparing
the trimmed length against the stored one also makes the condition exact:
it fires when the value really was clamped, not merely when it was long.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions Bot left a comment

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.

No blocking issues found.

@mateoHernandez123
mateoHernandez123 merged commit 12539c8 into main Aug 26, 2026
11 checks passed
@mateoHernandez123
mateoHernandez123 deleted the mateoHernandez123/okta-group-description-entitlements branch August 26, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants