Skip to content

Auth: "redirect straight to the identity provider" — with SSO configured, skip the sign-in page and return to the original page; the local sign-in path is configurable #33183

Closed

Description

@objectstack-fleet

repo:cloud#5 · hotlong · session_01Q4EjjPP1zuWBNq3nBXVei9

Filing gate: ④ a child of the topic card objectstack-ai/cloud#4465 (the maintainer's rulings 1-10 of 2026-11-13/14 are recorded there; read it first).

维护者速读

平台统一功能:开了单点登录后,打开环境不再显示登录页,直接跳到身份提供方,登录后回到原来的页面。本地登录入口可以配置:自托管可以保留一个隐藏地址;托管上关闭,按裁决 10,托管没有本地登录。云端会把这个功能默认打开。

Work (objectstack-ai/cloud#4465 ruling 8, child 4a)

  • Add one setting: when SSO is configured, an unauthenticated visit goes straight to the configured IdP, preserving the return URL.
  • The local sign-in path is configurable: on with a hidden path (for example /login?local=1), or off.
  • Self-hosted deployments with their own IdP can enable it. The cloud enables it by default with the local path off (cloud card C6).
  • API keys, MCP and the API are unaffected.

Suggested priority:p1. Routing: triage (plugin-auth plus the console login page).

priority:p1 on the maintainer's word, verbatim (seat session session_01Q4EjjPP1zuWBNq3nBXVei9, 2026-11-14): 「都是p1,车道自己认领就可以」. Triage routes it to its lane; the lane claims it.

Activity

  1. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: routed → domain:server · p1 · pm:queue · 2026-11-14T00:45Z

    ⛔ Not a claim.

    • Grade p1 on the maintainer's word, verbatim: 「都是p1,车道自己认领就可以」 (seat session session_01Q4EjjPP1zuWBNq3nBXVei9). This is a child of objectstack-ai/cloud#4465, which records rulings 1–10: people are added in the environment, and credentials stay in the cloud.
    • Owner: plugin-auth (the redirect setting and return URL). The console login page's half can ride the same PR, or a domain:ui follow-up if it is separate.
  2. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Claim: PM loop round 15, card thread · 2026-11-14T02:18Z · p1 on the maintainer's word 「都是p1,车道自己认领就可以」 (triage 6868751351)
    Session: session_01L9qibzj132D7VvPtkgPSrV
    Account: os-tesla
    Branch: claude/project-thread-zr8ir4
    Worktree: objectstack-issue-33183
    Domain: domain:server
    Seat: domain:server#7
    File surface: packages/plugins/plugin-auth/src/ — the setting, the redirect decision and the return-URL check; the Console sign-in route or page only if the shape note puts that half here; packages/spec/src/ only if the shape note names it and the seat accepts it; their tests; the auth docs page for the setting; one root changeset. Every file is named in a shape note before code. Stop on breach.
    Container & model: L, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; PM default), effort: high
    Clause-②: yes (widening) — a new setting, off by default; nothing changes until it is set; the shape note names any default or existing answer that moves
    Metadata-protocol: none — unless the setting lands in an authorable spec schema, which the shape note states before code
    Responsibility: an environment with SSO configured still shows its local sign-in page (plugin-auth plus the Console sign-in route), objectstack | a user can click through to the IdP by hand | every SSO environment's users, and hosted environments, where the cloud has no local sign-in to offer
    Thread-read: 6868751351
    Premise: re-measure — how an unauthenticated visit reaches the sign-in page, how an IdP sign-in keeps its return URL, and which doors must never redirect, measured at origin/main first
    Serial constraints cleared: security#2's PR #33177 has merged (30e364ea); this seat's #33181 edits other plugin-auth seams (the password doors and session creation for pending rows), so this card keeps away from both. The maintainer's rulings on objectstack-ai/cloud#4465 (8 and 10) are outside this session's reach and nothing is inferred from them.

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  4. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Claim amendment to this seat's claim 6870084529 on #33183 · 2026-11-14T02:23Z: the seat accepts the shape note out/33183-proposed-shape.md (measured at origin/main 66919b6), with these choices.

    The setting. It is a plugin option plus host environment variables, not an authorable spec key. Metadata-protocol: none, and Clause-②: yes (widening) because it is off by default.

    The file surface adds:

    • packages/plugins/plugin-auth/src/direct-sign-in.ts (new), auth-manager.ts, auth-plugin.ts;
    • packages/spec/src/kernel/public-auth-features.ts and its test: one classification entry for the served features.directSignIn flag, and localSignIn as a non-flag key;
    • the Console half in this PR (Fixes #33183): ui/apps/console/src/pages/auth/LoginPage.tsx and ui/packages/auth/src/types.ts;
    • their tests, the auth docs page, and the changeset.

    Behaviour:

    • "Local sign-in off" is decided on the page only in this PR. The server's password sign-in is unchanged, so the break-glass path ADR-0135 D5.2 keeps stays reachable. A server-side refusal waits for the maintainer's ruling text.
    • The OAuth client hand-off on /login is not redirected.
    • The return path is kept only when it is a same-origin relative path. Any other value is replaced by the Console root.
  5. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Second claim amendment to this seat's claim 6870084529 on #33183 · 2026-11-14T02:32Z: the file surface adds three groups the accepted shape forces.

    • packages/spec/src/api/auth-endpoints.zod.ts: directSignIn and localSignIn on AuthFeaturesConfigSchema, the served /auth/config response schema. The registry-to-schema pin keeps it equal to public-auth-features.ts and the served keys. It is a response schema, not an authorable key, so Metadata-protocol: none stands.
    • The Console half:
      • ui/apps/console/src/pages/auth/directSignIn.ts (new): the pure redirect decision;
      • ssoCallbackRefusal.ts: the door's direct_sign_in_unavailable code;
      • the 11 locale files in ui/packages/i18n/src/locales: four new strings.
    • packages/plugins/plugin-auth/src/index.ts: exports the option type.

    The platform IdP start uses better-auth's /sign-in/social with providerId, because the genericOAuth providers are served there. The environment variables are OS_AUTH_DIRECT_SIGN_IN_ENABLED, OS_AUTH_DIRECT_SIGN_IN_PROVIDER and OS_AUTH_LOCAL_SIGN_IN.

  6. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    repo:cloud#5 · hotlong · session_01Q4EjjPP1zuWBNq3nBXVei9

    Ruling text relayed 2026-11-14T03:07Z, on the maintainer's request in seat session session_01Q4EjjPP1zuWBNq3nBXVei9: 「server agent 项目读不到 cloud 仓库,请把原文贴到两张卡上」. This card carries ruling 8 of objectstack-ai/cloud#4465 (private repo); ruling 10 sets the hosted local path. Below is the verbatim text of that card's body as last edited at 2026-11-14T03:05Z. The cloud-side half (hosted default on, local path off, the cloud sign-in page showing the organization's name) is objectstack-ai/cloud#4471, blocked by this card.

    Rulings 8 and 10 (the maintainer, 2026-11-13), verbatim

    1. Direct redirect to the identity provider is a platform feature, on by default in the cloud. The maintainer, verbatim: 「开了单点登录后也可以设成「直接跳转身份提供方」,这个应该顺便开发平台统一的功能吧」 and 「只是云端默认打开」.

      • The framework gains one setting: when SSO is configured, an unauthenticated visit skips the environment's sign-in page and goes straight to the configured identity provider, then returns to the original page.
      • The local sign-in path is configurable. Self-hosted can keep a hidden path (for example /login?local=1). Hosted has it off (ruling 10).
      • Self-hosted deployments with their own IdP can turn it on. Hosted environments have it on by default, with the cloud as the provider. The cloud sign-in page shows the organization's name and explains refusals (not a member under D5.1; invitation not accepted).
    2. Hosted has no local break-glass admin. The maintainer chose 「A」.

    • No hosted environment sets a local password for anyone, and existing owner break-glass passwords are invalidated.
    • Emergency access is a platform-operator procedure, audited: the platform-admin disable_platform_sso / enable_platform_sso from cloud#3134, or a one-time recovery link.
    • Self-hosted deployments keep local admins.
    • This supersedes cloud#3132's "keep a break-glass local admin" for hosted.

    Ruling recorded after the body (comment 6870693029 on cloud#4465)

    d-2 应急入口不考虑 d-3 同意

    For this card: D-2 means no one-time recovery link is built, so ruling 10's "or a one-time recovery link" is not pursued. The hosted local sign-in path stays off with no emergency reopening. The configurable local path in ruling 8 still applies to self-hosted deployments.

  7. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Third claim amendment to this seat's claim 6870084529 on #33183 · 2026-11-14T04:35Z: the file surface adds the LoginForm of @object-ui/auth (under ui/packages/auth/) and its pin. When /auth/config serves features.localSignIn: 'off', the form hides the email and password form, sign-up and the break-glass link in every state, as it already does when emailPassword.enabled is false. This covers the two states that still fall back to the default page: an OAuth client hand-off, and directSignIn refined to false because no provider can start. It carries ruling 8 and ruling 10 on cloud#4465 as quoted on this card (comment 6870716068): hosted has the local path off, with no emergency reopening. A self-hosted hidden local path is unchanged.

  8. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzj132D7VvPtkgPSrV
    os-dev-report

    {
      "issue": 33183,
      "status": "done",
      "branch": "claude/project-thread-zr8ir4",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/33221",
      "session": "session_01L9qibzj132D7VvPtkgPSrV",
      "premise_still_valid": true,
      "summary": "Direct sign-in, the framework half of ruling 8: a plugin-auth setting (`directSignIn` option, OS_AUTH_DIRECT_SIGN_IN_ENABLED / _PROVIDER, OS_AUTH_LOCAL_SIGN_IN hidden|off) mounts GET /api/v1/auth/sign-in/direct, which keeps only a same-origin return path, starts the configured provider through the vendor's own start (/sign-in/social for objectstack-cloud, /sign-in/sso for an SSO row) and answers 302 with its state cookie. /auth/config serves features.directSignIn (true only while a provider can start) and localSignIn; PUBLIC_AUTH_FEATURES gains directSignIn, so requiresFeature accepts 'directSignIn'. The Console sign-in page goes straight to the door for a signed-out visitor and returns to the same URL marked direct=returned; the loop guard holds on error and on a sessionless return, keeps an OAuth hand-off on today's page, and with localSignIn off the form draws no local way in, in any state (D-2). The server's /sign-in/email is unchanged; hosted password invalidation is cloud#4471.",
      "tests": "plugin-auth full suite 269 files / 5184 passed / 10 skipped (direct-sign-in.test.ts 69, implicit-account-linking.test.ts round trip +4); spec full suite 839 files / 26834 passed, src/api 63 / 2063 after the ledger change; client route-ledger consumers 3 / 12; ui packages/auth 45 / 468; LoginPage.direct-sign-in.test.tsx 16. Ablations via scripts/ablation-replace.mjs, each restored to HEAD and verified: pin 1 kept path ignored 2 failed; pin 2 no // check 7, no backslash 5, no control-char 8, no decode layers 16, keep any string 51, keep any string without the composed-URL backstop 52; pin 3 ?local=1 honoured under off 2; pin 4 no error hold 2, no return hold 2; pin 5 door mounted when off 52, page starts without the flag 3; pin 6 door claims every GET 1; pin 7 LoginForm ignores localSignIn off 2. The URL-parse origin check inside keptReturnPath alone stays green: it is a backstop no input reaches alone.",
      "gates": "head f690739f after one merge of origin/main: dispatch-gates --commands 123 families, each run with </dev/null and exit recorded; --ran: 123 run, 0 NOT-MEASURED, 0 UNRUN, all exit 0. pnpm lint exit 0. First pass found 3 reds, fixed in the branch: check:auth-mount-ledger (literal mount path + public ledger row), check:error-code-provenance (NOT_FOUND row under plugin-auth), check:generated (heap OOM in check:test-typecheck; green with NODE_OPTIONS=--max-old-space-size=8192). PR check-runs not yet read: the PR was just opened.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "4 — mcp__github__issue_read x3, mcp__github__pull_request_read x1 (get_files on #33208); 0 writes",
      "api_writes": "1 relay write — fleet-write pr_create (#33221, assignees os-tesla, read back byte-identical); plus this os-dev-report comment via post-stamped; git pushes to claude/project-thread-zr8ir4",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: c · reach: exception: maintainer · the PR owes a contract review at TIER_DEFAULT (widening; Metadata-protocol: added) from the new review agent before it lands · carrier: PR #33221 · noted, not filed"
      ]
    }
  9. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Release: session_01L9qibzuZJBQY4wUQFJbkfx · seat domain:server#7 signs off on the maintainer's word 「所有座位当前任务处理完,合并后就下班」 (2026-11-14T04:35Z, project chat) and 「各座位自己的契约复审也暂停,等新的 review agent 上线后复审」 (2026-11-14T04:37Z) · back to pm:queue for the next claimant · 2026-11-14T06:10Z
    Resume-from: claude/project-thread-zr8ir4@f690739f8073555d17dce0a4221c9c6573cf48e6

  10. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Nov 14, 2026
  11. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Maintainer decision recorded · 2026-11-14T14:55Z: on the seat's decision card, which asked whether direct sign-in should send a person who has just pressed Sign out straight back to the identity provider, the maintainer chose 「Hold the sign-in page」. After an explicit sign-out the sign-in page stays, with a button to sign in again; only a fresh signed-out visit starts the identity provider automatically. This answers escalation E1 / finding F2 of contract review record 6879172654 on PR #33221, and the fix on that PR builds and pins it.

  12. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Claim: resume after the 04:35Z sign-off, card thread · 2026-11-14T17:23Z · the seat is back on duty for review and landing only (「你现在可以自己契约复审了。」 2026-11-14T14:17Z; 「车道座位应该使用pm-dispatch 技能审核和落地pr」 2026-11-14T14:32Z); PR #33221
    Session: session_01L9qibzj132D7VvPtkgPSrV
    Account: os-tesla
    Branch: claude/project-thread-zr8ir4
    Worktree: objectstack-issue-33183
    Domain: domain:server
    Seat: domain:server#7
    File surface: claim 6870084529 with amendments 6870153090, 6870264671 and 6871810774, plus ui/packages/auth/src/ (the sign-out round trip of review F6, decision 6879236460). Stop on breach.
    Container & model: L, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; PM default), effort: high
    Clause-②: yes (widening), as declared on PR #33221
    Metadata-protocol: added — requiresFeature: 'directSignIn' (this corrects the claim's earlier none)
    Responsibility: an environment with SSO configured still shows its local sign-in page (plugin-auth plus the Console sign-in route), objectstack | every SSO environment's users, and hosted environments | 18.4.0 onward
    Thread-read: 6881390951
    Premise: re-measured by the card thread; reviewed at CONTRACT_REVIEW_TIER (records 6879172654, 6880597586, 6881390951)
    Serial constraints cleared: #33177 merged; #33227 (this seat's #33181) touches other plugin-auth seams

  13. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  14. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzj132D7VvPtkgPSrV

    Correction to this card's dev report 6872305139 and the claim it carries: the claim's Metadata-protocol: none line is stale. PR #33221 is Metadata-protocol: added (the new requiresFeature: 'directSignIn' value on the PUBLIC_AUTH_FEATURES registry), with Clause-②: yes (widening) and Skills-docs: none and its reason, as its PR body and changeset say.

    Contract review on PR #33221: FAIL 6879172654 at a808f407, delta PASS 6880597586 at 4fab4525 (should-fix F5, F6), second delta PASS 6881390951 at d990af409b7471abae9a5291bb34d81dcaffcd3b with no must-fix or should-fix open. The sign-out hold follows the ruling 6879236460, also across an identity-provider logout round trip.

  15. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

    Landed · 2026-11-14T18:26Z: PR #33221 merged as 4dbcbddd, which closes this card. The follow-up is #33358. Removing pm:dispatched.

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

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions