Add IdP directory reads, email invites, and a member picker - #149
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
HiranAdikari
force-pushed
the
feat/idp-directory
branch
3 times, most recently
from
June 11, 2026 08:04
77523cc to
3ad00fb
Compare
Inviting a member previously required pasting the raw OIDC sub from the invitee's JWT. dc-api now supports an optional read-only SCIM2 directory provider (DCAPI_IDP_* config, dark when unset): invites accept an email that is resolved to the sub at invite time, owner- gated directory endpoints list users and groups with minimal fields, cloud-ui's grant dialog gains a directory-backed member picker, and dcctl tenant member commands accept the email form. Reads are proxied live and never persisted; the database keeps storing only the sub and display alias. The Flux base wires the new config (placeholders keep the feature dark), the consumer overlay template documents how to enable it, and init-flux.sh seal auto-pulls the directory credential from the asgardeo-auth layer's terraform outputs. The seal flow also now preserves the live Postgres password and BFF session secret on re-runs, so re-sealing a live environment no longer rotates the database password out from under dc-api.
HiranAdikari
force-pushed
the
feat/idp-directory
branch
from
June 11, 2026 08:15
3ad00fb to
0305610
Compare
gnudeep
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Inviting someone to a tenant previously required pasting their raw OIDC
sub— an opaque UUID the inviter had to dig out of the invitee's JWT. This PR lets dc-api read users and groups from the IdP (read-only, over SCIM2), so inviters can grant roles by email or by browsing a member picker, the way Azure's "Add role assignment" works.Privacy guardrails (enforced in code)
Directory reads are proxied live and never persisted — the database stores only the OIDC
suband a display alias copied once at grant time. Responses expose minimal fields only (name, email, sub, group names). Directory listing is gated to principals holdingauthorization/roleAssignments/write, and the machine-to-machine credential carries read-only VIEW scopes. The feature is entirely dark when theDCAPI_IDP_*config is unset. Recorded as decision 8 indocs/decisions.md.The pieces
dc-api — new
internal/directorypackage (Provider interface + SCIM2 client with OAuth2 client_credentials and a short-TTL cache), configured by four optionalDCAPI_IDP_*variables; completely dark when unset.POST …/role-assignmentsacceptsuser_emailas an alternative touser_sub(resolved to the sub at grant time; 422 when the email doesn't match exactly one user or no directory is configured). NewGET /v1/tenants/{id}/directory/users|groupsendpoints: paginated, filterable, 501 when unconfigured (the feature-detection signal clients probe), 502 with a generic body on IdP failure (upstream detail only in server logs).cloud-ui — the Add role assignment dialog gains an Azure-style member picker: a panel listing the directory on open with search and pagination; picking a user pins the resolved sub and uses their IdP display name as the alias (the manual display-name field is gone). Deployments without a directory keep the old raw-sub input.
dcctl —
tenant member create alice@example.com --role Contributornow works (email is the documented primary form). The member commands were also migrated off the removed v1 members API onto role-assignments with RBAC v2 role keys, and the generated client was refreshed from the current spec.Deployment wiring — the Flux base carries the new config (
dc-api-configplaceholders + optionalsecretKeyRefentries; absent values keep the feature dark), the consumer overlay template documents how to enable it, andinit-flux.sh sealauto-pulls the directory credential from the asgardeo-auth layer's terraform outputs. The seal flow also now preserves the live Postgres password and BFF session secret on re-runs (re-sealing a live environment used to rotate the DB password out from under dc-api) and drops the retired ARC runner PAT, whose orphaned SealedSecret failed the whole platform Kustomization apply.Also fixed in passing: the contract-test tag list still referenced the v1
memberstag, which no longer exists in the spec — role-assignment operations had silently dropped out of contract coverage. The tag is nowroleAssignments(+directory), raising covered operations from 30 to 50.Verification
Unit: dc-api suite green including 9 SCIM2 client tests (httptest mock IdP) and 20 handler tests. Integration: 13 new tests for email invites + directory endpoints, run green in cluster-free mode against real Postgres. Contract: schemathesis, 50 operations / 4864 generated cases, 0 failures. Live: verified end-to-end on a local stack against a mock SCIM2 IdP — directory list/filter/paging, email invite happy path, ambiguous and unknown email 422s, dark-mode 501/422, raw-sub regression, dcctl CLI flow, and a DB check confirming only the sub and alias are persisted. cloud-ui: tsc, eslint, vitest clean; dcctl: builds with go vet clean.
Note: rebased on controlplane after #147 merged — the diff is now the feature only.
🤖 Generated with Claude Code