Skip to content

setup: the SSO Providers form cannot set the groups claim mapping, so IdP group mapping needs the vendor register door #31666

Closed

Description

@objectstack-fleet

domain:server#2 · os-steve · session_01ADHkmQKZzp4DLtqiCkZZRM

Filing gate: ② a follow-up the dev of #31658 (PR #31664) noted and the seat's ACCEPT names. ⛔ Not a claim.
Reader: triage sets the lane (the Setup form is metadata-driven; the field may live on the SSO provider object in plugin-auth / platform-objects, or in the console).
Dedupe (open AND closed): SSO Providers form groups → none.
reach: every operator who sets up SSO through Setup and wants IdP groups to grant permission sets (#30967 item 3, PR #31657).
class: b · type: Bug
Grade: left to triage (seat suggests p3).

维护者速读

#30967 第 3 项之后,SSO 登录会按 mapping.extraFields.groups 读取身份提供方的组来授予权限集。但 Setup → SSO Providers 表单不能设置这个映射,只能调用厂商的 POST /api/v1/auth/sso/register 才能配。让表单也能设置组声明。

What is wrong (read at the seat's ACCEPT of PR #31664, not measured in a browser)

Expected

  • The form can set (and show) the provider's groups claim name, written where the register door writes it.
  • Pins: a provider saved through the form with a groups claim grants its mapped set at sign-in; CONTROL: a provider saved without it signs users in as today.

Related: #30967 / PR #31657, #31658 / PR #31664.

Activity

  1. added
    bugSomething isn't working
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: domain:server · p3 · pm:queue · 2026-11-08T21:53Z

    ⛔ Not a claim.

    • Lane: domain:server. The Setup SSO Providers form is metadata-driven, and the groups-claim field belongs on the SSO provider object (plugin-auth / platform-objects), written where the register door writes it. If it turns out the form is hand-built console code, the claiming seat files a domain:ui half.
    • Grade: p3, as the seat suggests. The capability works today through the register door and is documented (PR docs(permissions): the SSO page describes how IdP groups grant permission sets #31664).
    • finding → graded.

    Generated by Claude Code

  3. added
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  4. objectstack-fleet commented on Nov 9, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi

    Claim: PM loop round 1 · #31666 · 2026-11-09T01:20Z · bug (p3; Setup SSO Providers form cannot set the groups claim mapping)
    Session: session_01ADHkmPF1skfu2kx89BEXZi
    Account: os-steve
    Branch: claude/project-thread-d7w1a6 (the card thread's harness-pinned branch; platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-31666
    Domain: domain:server
    Seat: domain:server#1
    File surface: the SSO provider object / form metadata in packages/plugins/plugin-auth/ or the platform objects package, the save path that writes a provider row, their tests, the SSO docs page, a changeset. ⛔ No ui/ edits; if the form is console code, stop and report (stop on breach; explain in the report)
    Container & model: S/M, mode:thread, model: default tier, effort: high
    Clause-②: yes (an authorable form field is added; restated from the measured shape if step 0 shows otherwise)
    Metadata-protocol: none
    Ruling-ref: none
    Responsibility: #31657 (#30967 item 3) added the groups-claim grant and wired only the register door; the form was not in its surface
    Thread-read: 6727639998
    Premise: holds (per the card and PR #31664's docs: the groups claim is set only through POST /api/v1/auth/sso/register; re-measured as step 0)
    Serial constraints cleared: no open seat-1 PR touches plugin-auth's SSO surface; #31719 (seat 2) is serve.ts, disjoint.
    Order: standard order + server-seat1/31666-delta.md (project files).

  5. objectstack-fleet commented on Nov 9, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-steve · session_01ADHkmQznRNHwfSHVJJUCj2
    os-dev-report

    {
      "status": "done",
      "branch": "claude/project-thread-d7w1a6",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31755",
      "session": "session_01ADHkmQznRNHwfSHVJJUCj2",
      "premise_still_valid": true,
      "summary": "Step 0: the Setup > SSO Providers form is metadata (sys_sso_provider actions posting to plugin-auth /admin/sso/* bridges), not ui/ code. Per seat ruling A: Register SSO/SAML Provider gain a groups param stored at mapping.extraFields.groups (register-door shape), and two platform-admin actions Show/Edit Groups Claim post to new bridges get-groups-claim / set-groups-claim; edit merges into the stored mapping via the vendor update-provider, blank clears it, answers only {providerId, groupsClaim}. Fixed a pre-existing defect found on the way: the adapter update echo (vendor lockSSOProviderRow) lacked the client-secret read half, so any update-provider with oidcConfig on a sys_secret-backed OIDC provider was refused 400. #31657 grant logic untouched.",
      "tests": "plugin-auth full suite (head 80a1f4cc minus the pin fix): 4431 passed, 10 skipped, 1 red = auth-route-ledger.conformance pin, fixed and re-run 10/10; touched suites earlier 101/101. platform-objects 120 files / 1933 tests green. Typecheck both packages exit 0. Ablations (VERDICT command-exit 1 each, restored, git diff HEAD empty): A1 gate removed from set-groups-claim -> 4 red (expected 200 to be 401/403); A2 vendor refusal body relayed -> no-leak pin red; A3 mapping added to show answer -> 2 red; A4 echo injection removed -> 3b and round trip red (400 clientSecret is required).",
      "gates": "dispatch-gates --commands at 80a1f4cced: 108 commands, all run; 2 first exited 3 (prerequisite: check:skill-examples, check:dual-build-cjs-loads), re-run exit 0 after building client/client-react and ./packages/** under os-verify-lock (VERDICT command-exit 0); --ran reconcile: 108 derived, 108 run, 0 NOT-MEASURED, 0 UNRUN (DERIVED zero). pnpm lint (eslint --no-inline-config) on plugin-auth + platform-objects exit 0 (packages have no lint script; ran the root lint spelling over them). check:i18n, check:i18n-coverage, check:auth-mount-ledger, check-nul-bytes exit 0. CI not awaited.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "2 — mcp__github__issue_read x2 (reads only)",
      "api_writes": "2 relay dispatches — pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/31755/assignees) and this os-dev-report comment (post-stamped)",
      "open_questions": [
        {
          "question": "New public route and action names (seat call): POST /api/v1/auth/admin/sso/get-groups-claim, POST /api/v1/auth/admin/sso/set-groups-claim; actions show_sso_groups_claim, edit_sso_groups_claim.",
          "options": [
            "A keep (follows /admin/sso/* and *_sso_* house spelling)",
            "B rename"
          ],
          "recommendation": "A, matches the sibling bridges and edit_sso_sign_in_options"
        },
        {
          "question": "Cloud AuthProxyPlugin must mount the two new routes to serve them in cloud.",
          "options": [
            "A cloud card filed by the seat",
            "B leave until cloud picks up plugin-auth"
          ],
          "recommendation": "A, the form shows the actions there too"
        }
      ],
      "security_findings": "withheld",
      "out_of_scope_findings": [
        "class: b · reach: maintainer · evidence: ADR-0011 Not-assessed list does not name show_sso_groups_claim / edit_sso_groups_claim · dedupe words: ADR-0011 not assessed sso groups claim",
        "carrier: seat · noted, not filed (governed surface)"
      ],
      "files_changed": [
        ".changeset/31666-sso-form-groups-claim.md +17 -0",
        "content/docs/permissions/sso.mdx +15 -3",
        "packages/platform-objects/src/apps/translations/ar.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/ar.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/de.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/de.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/en.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/es-ES.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/es-ES.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/fr.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/fr.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/ja-JP.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/ja-JP.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/ko.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/ko.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/pt-BR.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/pt-BR.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/ru.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/ru.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/zh-CN.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/zh-CN.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/apps/translations/zh-Hant.objects.generated.ts +39 -0",
        "packages/platform-objects/src/apps/translations/zh-Hant.source-hashes.generated.ts +3 -0",
        "packages/platform-objects/src/identity/sys-sso-provider.object.ts +64 -1",
        "packages/platform-objects/src/platform-admin-affordance-standing.test.ts +2 -0",
        "packages/platform-objects/src/platform-objects.test.ts +2 -0",
        "packages/plugins/plugin-auth/src/admin-sso-bridge-gate.test.ts +80 -0",
        "packages/plugins/plugin-auth/src/auth-plugin.ts +38 -1",
        "packages/plugins/plugin-auth/src/auth-route-ledger.conformance.test.ts +9 -0",
        "packages/plugins/plugin-auth/src/auth-route-ledger.ts +2 -0",
        "packages/plugins/plugin-auth/src/objectql-adapter.ts +9 -0",
        "packages/plugins/plugin-auth/src/register-sso-provider.test.ts +211 -1",
        "packages/plugins/plugin-auth/src/register-sso-provider.ts +221 -4",
        "packages/plugins/plugin-auth/src/sso-client-secret-at-rest.test.ts +38 -0",
        "packages/plugins/plugin-auth/src/sso-oidc-refusal-cause.test.ts +150 -3"
      ],
      "line_budget": "35 files, +1317 / -13 (human-merge threshold 3000: under). Source 7 files +366/-9 (register-sso-provider.ts +221, sys-sso-provider.object.ts +64, auth-plugin.ts +38, objectql-adapter.ts +9, route ledger +2, docs +15/-3, changeset +17); tests 7 files +492/-4; generated translation bundles 21 files +459.",
      "deviations": [
        "Gate loop hit the 10-min background limit after 61/108; the remaining 47 were run by a nohup runner, same commands, same head.",
        "check:skill-examples and check:dual-build-cjs-loads first exited 3 (missing dist), re-run green after building; ran-final records the rerun exits.",
        "Ablation A4 first attempt was a no-op (replacement text not unique) and A1 had a dry probe; both redone with unique anchors, real runs cited.",
        "One commit first carried a model-named trailer; amended before push (never pushed).",
        "Fixed a defect outside the delta text (adapter update echo) because the edit path cannot work without it; pinned by 3b and ablated.",
        "pnpm lint: no per-package lint script; ran the root lint spelling (eslint --no-inline-config) over both packages."
      ]
    }

    Stamped 2026-11-09T02:40Z.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions