You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SCIM connection credentials: add a Setup action for mint and revoke #31032
#30991 shipped the two platform-admin routes POST /api/v1/auth/admin/scim/mint-credential and POST /api/v1/auth/admin/scim/revoke-credential, documented as curl calls in authentication.mdx. There is no way to reach them from the console. A platform administrator setting up SCIM provisioning still has to use the command line to get a bearer token.
What
A type: api action on the SCIM connection credential object that calls the mint route and shows the token once in a result dialog. The token is never stored or shown again.
A revoke action on a credential row, calling the revoke route (it already answers 404 / 409).
Platform-objects translations for both actions, and an AI exposure classification for each.
Optional, from contract review 6689658194 (nit 4): the mint door's own audit row could carry metadata.impersonatedBy, so the row says who acted on an impersonation session. /admin/create-user's row doesn't do this either today.
Out of scope
Letting an organization administrator mint, which would widen who can mint. That is a maintainer decision and is not proposed here.
p2: the routes already exist, and this is console reach for them. Lane domain:server kept (platform-objects actions). pm:queue.
⚠️ For the AI exposure classification the card asks for: an agent that can run the mint action would get a live bearer in its context. Classify mint as not exposed to AI tools. Exposing it is a security boundary, so it goes on a decision card first. Revoke may be classified on its own merits.
Organization-admin minting stays out of scope, as the card says (a decision card if it is ever wanted).
Claim: PM loop round 1 · 2026-11-07T12:25Z
Session: session_017ihL2dFb2QdZEHEJ83cR2B
Account: marchtian
Branch: claude/project-thread-6pto5z
Worktree: objectstack-issue-31032 (the card thread's own checkout)
Domain: domain:server
Seat: domain:server#3
File surface: packages/platform-objects/** (the SCIM credential/binding objects, translations via tooling); optionally packages/plugins/plugin-auth/src/scim-connection-admin.ts for the card's item 4 (stop on breach; explain in the report)
Container & model: M, mode:thread (card thread cmsg_01VmuUhXU9SSUzqJYyXSmYSiGwrQnU7LLG4tMfKYbWXT48 of this account's project), model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate, effort: session default — card-thread effort is set by the maintainer only; the seat's reading is high (M)
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6692886264
Premise: holds — read at origin/main 5f00374: both platform-admin routes exist in plugin-auth; sys-scim-connection-credential.object.ts carries no actions
Serial constraints cleared: #31033 (one-line cap fix in scim-connection-admin.ts) is held behind this card, not dispatched; open PR #31013 touches other plugin-auth files (auth-manager-plugin-list.ts, auth-manager-after-hook.ts, auth-plugin.ts), disjoint; siblings #31085/#31029 (this seat) touch other platform-objects files
The dispatch order is the card thread's opening message (files server-seat-3/orders/_standing.md + server-seat-3/orders/31032.md in this account's project); slot granted by the project coordinator.
{
"issue": 31032,
"status": "done",
"branch": "claude/project-thread-6pto5z",
"pr": "https://github.com/objectstack-ai/objectstack/pull/31119",
"session": "session_017ihL2c3bRFyY1fQ6vWAW1Z",
"premise_still_valid": true,
"summary": "sys_scim_connection_credential gains mint_scim_credential (list toolbar, type api, POST the mint mount, params named for the mount's body keys connectionId/label/organizationId/provisioningDomainId/expiresAt, token revealed once in a resultDialog) and revoke_scim_credential (list item + record header, POST the revoke mount, recordIdParam credentialId, confirmText, offered on active rows only). Both are offered only on current_user.isPlatformAdmin and declare PLATFORM_ADMIN_SETTINGS_GATE, the same declarations every /api/v1/auth/admin/ action carries; the mounts' gate is unchanged and no second permission path exists. AI: mint bucket H (no ai block), revoke bucket C (exposed, requiresConfirmation). Precedent for the one-shot reveal: sys_api_key.create_api_key and sys_oauth_application.create_oauth_application. Mint sits on the credential object because the mount is keyed by connectionId and writes a credential row; the binding object is never read by it. Item 4 taken: a mint on an impersonation session writes metadata.impersonated_by (plugin-audit's IMPERSONATED_BY_KEY spelling, not the card's impersonatedBy) into its own sys_audit_log row; revoke's row unchanged.",
"tests": "New sys-scim-connection-credential-actions.test.ts (6 cases). two-factor-one-shot-reveal.test.ts: mint route added to ONE_SHOT_ROUTES (token). platform-admin-affordance-standing.test.ts: both sites in the family floor. plugin-auth scim-connection-admin.test.ts: impersonation mint case (forged body key ignored). Full suites at 82b61834: platform-objects 118 files / 1644 passed; plugin-auth 232 files / 4190 passed, 10 skipped. Ablations via scripts/ablation-replace.mjs, each landed, red, restored blob == HEAD: mint ai.exposed true (exposure pin red), revoke visible without the active guard (visibility pin red), resultDialog secret path token changed (one-shot class pin + mint pin red), revoke without requiresConfirmation (C pin red), plugin-auth always writing impersonated_by (ordinary-mint exact-metadata pin red). Sources are imported from src in both suites, so no dist leg.",
"gates": "typecheck (platform-objects + plugin-auth, incl. check:test-typecheck) :: exit 0 (first run exit 1 on a TS18048 in the new test, fixed in 82b61834). eslint --no-inline-config packages/platform-objects packages/plugins/plugin-auth :: exit 0. check-i18n-bundles --write re-run: no diff; pnpm check:i18n :: exit 0. dispatch-gates --commands derived 63 families at e2bf9dbe, identical at 82b61834; all 63 run with exit codes; two exited 3 first (check-plugin-teardown-shape --self-test: fixture commit fetched; check:dual-build-cjs-loads: packages built by check:type-check-debt) and re-ran exit 0. --ran: 63 derived, 63 run, 0 NOT-MEASURED (derived zero). CI check-runs: in_progress at report time (PR just opened).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay pr_create (PR #31119); this os-dev-report comment via post-stamped.mjs on #31032; git push is not a REST write",
"open_questions": [
{
"question": "Setup navigation: no entry reaches sys_scim_connection_credential (SETUP_NAV_CONTRIBUTIONS and plugin-auth's contributions name it nowhere), so the actions exist but a platform admin has no menu item to the list.",
"options": [
"A: a follow-up card adds a SCIM Credentials item to plugin-auth's navigationContributions beside the SSO one, contributed only while SCIM is wired (auth-plugin.ts; open PR #31013 touches that file)",
"B: a static entry in platform-objects setup-nav.contributions.ts (no scim public auth feature exists to gate it, so it would show while SCIM is off and the mint would answer 503)",
"C: leave it; operators open the object by URL"
],
"recommendation": "A, because it follows the SSO precedent (ADR-0029 K2 owning-plugin-contributes) and shows the entry only when the mint can succeed"
},
{
"question": "ADR-0011's identity-actions addendum table (read by reviewers, no automatic check) does not list mint_scim_credential (H) or revoke_scim_credential (C). Updating it is a Tier H ADR edit outside this card's file surface.",
"options": [
"A: the seat carries a one-line-per-action ADR amendment as its own Tier H PR",
"B: fold it into this PR (makes #31119 Tier H)",
"C: leave the table stale"
],
"recommendation": "A, keeps this PR off the governed surface"
}
],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · the revoke door's sys_audit_log row does not carry impersonated_by on an impersonation session (item 4 was scoped to the mint door by the order; same few lines in writeCredentialAudit's revoke caller) · noted, not filed",
"carrier: none · per-action AI-exposure pins added here, as the order asked; the ADR-0011 addendum records the maintainer striking a table-wide automatic check, and these pins are scoped to the two new actions only · noted for the seat's review"
],
"deviations": [
"Item 4 key spelled impersonated_by (the audit writers' IMPERSONATED_BY_KEY), not the card's metadata.impersonatedBy",
"es-ES result-dialog token label rendered Token de portador rather than the loanword Token, so no new en-echo row enters the es-ES provenance table",
"pnpm lint has no per-package script; ran root eslint (same flags) over the two touched package directories"
],
"line_budget": "12 files, +504 / -2 (under the 3000 human-merge threshold); 216 of the added lines are generated translation bundles",
"files_changed": [
".changeset/scim-credential-mint-revoke-actions.md",
"packages/platform-objects/src/identity/sys-scim-connection-credential.object.ts",
"packages/platform-objects/src/identity/sys-scim-connection-credential-actions.test.ts",
"packages/platform-objects/src/identity/two-factor-one-shot-reveal.test.ts",
"packages/platform-objects/src/platform-admin-affordance-standing.test.ts",
"packages/platform-objects/src/apps/translations/en.objects.generated.ts",
"packages/platform-objects/src/apps/translations/zh-CN.objects.generated.ts",
"packages/platform-objects/src/apps/translations/zh-Hant.objects.generated.ts",
"packages/platform-objects/src/apps/translations/ja-JP.objects.generated.ts",
"packages/platform-objects/src/apps/translations/es-ES.objects.generated.ts",
"packages/plugins/plugin-auth/src/scim-connection-admin.ts",
"packages/plugins/plugin-auth/src/scim-connection-admin.test.ts"
]
}
Activity
objectstack-fleet commentedon Nov 6, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p2 ·
domain:server· 2026-11-06T18:56Z⛔ Not a claim.
mintScimConnectionCredentialhas no caller and the object refuses create), so no IdP can connect #30958 (PR feat(plugin-auth): a platform administrator can mint and revoke SCIM connection credentials #30991): Setup actions that mint and revoke a SCIM connection credential through the two platform-admin routes, so a platform admin does not need curl. The token is shown once, never stored or shown again.domain:serverkept (platform-objectsactions).pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:server#3 · marchtian · session_017ihL2dFb2QdZEHEJ83cR2B
Claim: PM loop round 1 · 2026-11-07T12:25Z
Session:
session_017ihL2dFb2QdZEHEJ83cR2BAccount:
marchtianBranch:
claude/project-thread-6pto5zWorktree:
objectstack-issue-31032(the card thread's own checkout)Domain:
domain:serverSeat:
domain:server#3File surface:
packages/platform-objects/**(the SCIM credential/binding objects, translations via tooling); optionallypackages/plugins/plugin-auth/src/scim-connection-admin.tsfor the card's item 4 (stop on breach; explain in the report)Container & model:
M,mode:thread(card thread cmsg_01VmuUhXU9SSUzqJYyXSmYSiGwrQnU7LLG4tMfKYbWXT48 of this account's project),model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate,effort: session default — card-thread effort is set by the maintainer only; the seat's reading is high (M)Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6692886264
Premise: holds — read at origin/main 5f00374: both platform-admin routes exist in plugin-auth; sys-scim-connection-credential.object.ts carries no actions
Serial constraints cleared: #31033 (one-line cap fix in scim-connection-admin.ts) is held behind this card, not dispatched; open PR #31013 touches other plugin-auth files (auth-manager-plugin-list.ts, auth-manager-after-hook.ts, auth-plugin.ts), disjoint; siblings #31085/#31029 (this seat) touch other platform-objects files
The dispatch order is the card thread's opening message (files
server-seat-3/orders/_standing.md+server-seat-3/orders/31032.mdin this account's project); slot granted by the project coordinator.objectstack-fleet commentedon Nov 7, 2026
domain:server#3 · marchtian · session_017ihL2c3bRFyY1fQ6vWAW1Z
os-dev-report
{ "issue": 31032, "status": "done", "branch": "claude/project-thread-6pto5z", "pr": "https://github.com/objectstack-ai/objectstack/pull/31119", "session": "session_017ihL2c3bRFyY1fQ6vWAW1Z", "premise_still_valid": true, "summary": "sys_scim_connection_credential gains mint_scim_credential (list toolbar, type api, POST the mint mount, params named for the mount's body keys connectionId/label/organizationId/provisioningDomainId/expiresAt, token revealed once in a resultDialog) and revoke_scim_credential (list item + record header, POST the revoke mount, recordIdParam credentialId, confirmText, offered on active rows only). Both are offered only on current_user.isPlatformAdmin and declare PLATFORM_ADMIN_SETTINGS_GATE, the same declarations every /api/v1/auth/admin/ action carries; the mounts' gate is unchanged and no second permission path exists. AI: mint bucket H (no ai block), revoke bucket C (exposed, requiresConfirmation). Precedent for the one-shot reveal: sys_api_key.create_api_key and sys_oauth_application.create_oauth_application. Mint sits on the credential object because the mount is keyed by connectionId and writes a credential row; the binding object is never read by it. Item 4 taken: a mint on an impersonation session writes metadata.impersonated_by (plugin-audit's IMPERSONATED_BY_KEY spelling, not the card's impersonatedBy) into its own sys_audit_log row; revoke's row unchanged.", "tests": "New sys-scim-connection-credential-actions.test.ts (6 cases). two-factor-one-shot-reveal.test.ts: mint route added to ONE_SHOT_ROUTES (token). platform-admin-affordance-standing.test.ts: both sites in the family floor. plugin-auth scim-connection-admin.test.ts: impersonation mint case (forged body key ignored). Full suites at 82b61834: platform-objects 118 files / 1644 passed; plugin-auth 232 files / 4190 passed, 10 skipped. Ablations via scripts/ablation-replace.mjs, each landed, red, restored blob == HEAD: mint ai.exposed true (exposure pin red), revoke visible without the active guard (visibility pin red), resultDialog secret path token changed (one-shot class pin + mint pin red), revoke without requiresConfirmation (C pin red), plugin-auth always writing impersonated_by (ordinary-mint exact-metadata pin red). Sources are imported from src in both suites, so no dist leg.", "gates": "typecheck (platform-objects + plugin-auth, incl. check:test-typecheck) :: exit 0 (first run exit 1 on a TS18048 in the new test, fixed in 82b61834). eslint --no-inline-config packages/platform-objects packages/plugins/plugin-auth :: exit 0. check-i18n-bundles --write re-run: no diff; pnpm check:i18n :: exit 0. dispatch-gates --commands derived 63 families at e2bf9dbe, identical at 82b61834; all 63 run with exit codes; two exited 3 first (check-plugin-teardown-shape --self-test: fixture commit fetched; check:dual-build-cjs-loads: packages built by check:type-check-debt) and re-ran exit 0. --ran: 63 derived, 63 run, 0 NOT-MEASURED (derived zero). CI check-runs: in_progress at report time (PR just opened).", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — fleet-write relay pr_create (PR #31119); this os-dev-report comment via post-stamped.mjs on #31032; git push is not a REST write", "open_questions": [ { "question": "Setup navigation: no entry reaches sys_scim_connection_credential (SETUP_NAV_CONTRIBUTIONS and plugin-auth's contributions name it nowhere), so the actions exist but a platform admin has no menu item to the list.", "options": [ "A: a follow-up card adds a SCIM Credentials item to plugin-auth's navigationContributions beside the SSO one, contributed only while SCIM is wired (auth-plugin.ts; open PR #31013 touches that file)", "B: a static entry in platform-objects setup-nav.contributions.ts (no scim public auth feature exists to gate it, so it would show while SCIM is off and the mint would answer 503)", "C: leave it; operators open the object by URL" ], "recommendation": "A, because it follows the SSO precedent (ADR-0029 K2 owning-plugin-contributes) and shows the entry only when the mint can succeed" }, { "question": "ADR-0011's identity-actions addendum table (read by reviewers, no automatic check) does not list mint_scim_credential (H) or revoke_scim_credential (C). Updating it is a Tier H ADR edit outside this card's file surface.", "options": [ "A: the seat carries a one-line-per-action ADR amendment as its own Tier H PR", "B: fold it into this PR (makes #31119 Tier H)", "C: leave the table stale" ], "recommendation": "A, keeps this PR off the governed surface" } ], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · the revoke door's sys_audit_log row does not carry impersonated_by on an impersonation session (item 4 was scoped to the mint door by the order; same few lines in writeCredentialAudit's revoke caller) · noted, not filed", "carrier: none · per-action AI-exposure pins added here, as the order asked; the ADR-0011 addendum records the maintainer striking a table-wide automatic check, and these pins are scoped to the two new actions only · noted for the seat's review" ], "deviations": [ "Item 4 key spelled impersonated_by (the audit writers' IMPERSONATED_BY_KEY), not the card's metadata.impersonatedBy", "es-ES result-dialog token label rendered Token de portador rather than the loanword Token, so no new en-echo row enters the es-ES provenance table", "pnpm lint has no per-package script; ran root eslint (same flags) over the two touched package directories" ], "line_budget": "12 files, +504 / -2 (under the 3000 human-merge threshold); 216 of the added lines are generated translation bundles", "files_changed": [ ".changeset/scim-credential-mint-revoke-actions.md", "packages/platform-objects/src/identity/sys-scim-connection-credential.object.ts", "packages/platform-objects/src/identity/sys-scim-connection-credential-actions.test.ts", "packages/platform-objects/src/identity/two-factor-one-shot-reveal.test.ts", "packages/platform-objects/src/platform-admin-affordance-standing.test.ts", "packages/platform-objects/src/apps/translations/en.objects.generated.ts", "packages/platform-objects/src/apps/translations/zh-CN.objects.generated.ts", "packages/platform-objects/src/apps/translations/zh-Hant.objects.generated.ts", "packages/platform-objects/src/apps/translations/ja-JP.objects.generated.ts", "packages/platform-objects/src/apps/translations/es-ES.objects.generated.ts", "packages/plugins/plugin-auth/src/scim-connection-admin.ts", "packages/plugins/plugin-auth/src/scim-connection-admin.test.ts" ] }objectstack-fleet commentedon Nov 7, 2026
domain:server#3 · marchtian · session_017ihL2dFb2QdZEHEJ83cR2B
Landed · 2026-11-07T14:05Z
82b61834efFixes #31032State:
pm:dispatchedremoved.