{"$schema":"/schemas/d06-browser-auth-contracts.v1.schema.json","schemaVersion":"developer.reits.tech/d06-browser-auth-contracts/v1","observedAt":"2026-07-24T11:30:43Z","status":"D06_P1_CROSS_REPOSITORY_CONTRACT_CONTROL_PLANE_READY_D05_AND_ACTIVATION_BLOCKED","program":{"totalKnives":36,"acceptedKnives":4,"currentOrdinal":5,"currentKnife":"D05","candidateKnife":"D06","remainingIncludingCurrent":32,"remainingAfterD05":31,"d05GatesSatisfied":0,"d05GatesRequired":11,"d06Activated":false},"knife":{"id":"D06-P1","title":"Browser Auth cross-repository contract and migration control plane","kind":"PRE_ADMISSION_CONTRACT","repositoryImplementationComplete":true,"countsAsProgramAcceptance":false,"nextExecutableTask":"D05-T02","activationRequires":"D05_ACCEPTED_AND_LEDGER_CAS_TO_D06"},"sourceSnapshot":{"repositoriesFetched":4,"repositories":[{"id":"reits-auth","revision":"f5f96747e68936b38b3e793cb5a8e378771f3e3a","branch":"main","dirtyFiles":0,"evidence":[{"path":"internal/registry/clients.go","gitBlob":"c4745c4961b8c769d3be33342eca35a1414dfcbc","finding":"Three seeded browser-facing clients use 604800-second access-token TTLs; the registry has allowed origins and audiences but no redirect URI, grant, response, PKCE or post-logout registry."},{"path":"internal/httpapi/sessions.go","gitBlob":"3e69f04c43cbb730da8b63d739a84563309120c4","finding":"Durable refresh rotation and revocation primitives exist, but no browser authorization-code callback binds them to a relying party."},{"path":"docs/unified-account-auto-provision.md","gitBlob":"23185e5018d92b83779387839275b67855d276d9","finding":"Authorization Code, PKCE, Discovery and JWKS are explicitly absent; HS256 and seven-day token TTL remain documented blockers."}]},{"id":"miniapp-open-platform","revision":"71c16722492f2c96a2e57ed24ff56bda68f5f4d4","branch":"main","dirtyFiles":0,"evidence":[{"path":"packages/portal-web/src/auth.tsx","gitBlob":"f6208e38942ccc8d95ffef8ba1d7797af74ccb3c","finding":"reits.portal.token is read, written and removed in localStorage: three browser credential-storage operations."},{"path":"packages/portal-web/src/api.ts","gitBlob":"68e409fee451ba6afc5c41b4c73f390c24e0eca0","finding":"The portal attaches the stored Bearer token to API calls and login returns access_token directly to browser code."},{"path":"services/developer-api/cmd/server/main.go","gitBlob":"437bc6bfbd69ab51cdc8b1fbd0e198c92bb20e91","finding":"Login delegates with HTTP 421 and authBaseUrl but provides no one-time browser authorization transaction."}]},{"id":"public-booking-platform","revision":"6a38c3df682ea225d296ec9ec50a1407f26ac7d8","branch":"main","dirtyFiles":0,"evidence":[{"path":"apps/web/app.js","gitBlob":"cc8f1a5df20098c206e94c4469d805b920f841e1","finding":"matrixOrderToken accounts for thirteen localStorage credential operations and remains a Bearer fallback."},{"path":"apps/merchant-portal/app.js","gitBlob":"b8d1cf65ef4673ff807cf2042e5ce0eb196a05dc","finding":"merchantPortalToken adds three get/set/remove browser credential-storage operations."},{"path":"apps/api/server.js","gitBlob":"e827b220ad8e7f6bb7ec4467b37ac5e5434c8b76","finding":"An HttpOnly Secure SameSite=Lax member-session cookie is already a usable BFF migration foundation."}]},{"id":"opensdk","revision":"40d9219d607c60482c1ab11c4951296d29b22f22","branch":"main","dirtyFiles":0,"evidence":[{"path":"README.md","gitBlob":"d9dcfce9c1cb41d0d03d6b81c3c89815899fcc2e","finding":"Only a Go bot Bearer client is published; no browser start, callback, session, logout or step-up package exists."}]}]},"riskInventory":{"browserCredentialStorageOperations":19,"seededBrowserClientsWithSevenDayTtl":3,"registeredRedirectUris":0,"pkceCapableClients":0,"browserSdkPackages":0,"productionStateReceipts":0,"consoleStateReceiptsRequired":36},"clientRegistrations":[{"id":"open-portal-web","displayName":"Open Platform Portal","owner":"Open Platform","origin":"https://openapi.reits.tech","redirectUris":["https://openapi.reits.tech/auth/callback"],"postLogoutRedirectUris":["https://openapi.reits.tech/signed-out"],"audience":"miniapp-developer-api","scopes":["openid","profile","apps:read","apps:write"],"grantTypes":["authorization_code","refresh_token"],"responseTypes":["code"],"pkceMethod":"S256","tokenEndpointAuthMethod":"private_key_jwt","browserTokenCustody":false,"status":"PROPOSED_NOT_REGISTERED"},{"id":"booking-member-web","displayName":"Public Booking Web","owner":"Booking Consumer","origin":"https://order.reits.tech","redirectUris":["https://order.reits.tech/auth/callback"],"postLogoutRedirectUris":["https://order.reits.tech/signed-out"],"audience":"public-booking-api","scopes":["openid","profile","booking:read","booking:write"],"grantTypes":["authorization_code","refresh_token"],"responseTypes":["code"],"pkceMethod":"S256","tokenEndpointAuthMethod":"private_key_jwt","browserTokenCustody":false,"status":"PROPOSED_NOT_REGISTERED"},{"id":"booking-merchant-web","displayName":"Booking Merchant Portal","owner":"Booking Merchant","origin":"https://order.reits.tech","redirectUris":["https://order.reits.tech/merchant/auth/callback"],"postLogoutRedirectUris":["https://order.reits.tech/merchant/signed-out"],"audience":"public-booking-merchant-api","scopes":["openid","profile","merchant:read","merchant:write"],"grantTypes":["authorization_code","refresh_token"],"responseTypes":["code"],"pkceMethod":"S256","tokenEndpointAuthMethod":"private_key_jwt","browserTokenCustody":false,"status":"PROPOSED_NOT_REGISTERED"}],"contracts":[{"id":"AUTH-CN01","method":"GET","path":"/.well-known/openid-configuration","owner":"Identity Platform","browserExposure":"PUBLIC_METADATA","success":"Exact issuer, authorization endpoint, token endpoint, JWKS URI and S256 capability","failure":"ISSUER_METADATA_INVALID"},{"id":"AUTH-CN02","method":"GET","path":"/.well-known/jwks.json","owner":"Identity Security","browserExposure":"PUBLIC_KEYS_ONLY","success":"Active and retiring asymmetric verification keys with kid","failure":"JWKS_KEY_NOT_FOUND"},{"id":"AUTH-CN03","method":"POST","path":"/auth/start","owner":"Consumer BFF","browserExposure":"REDIRECT_ONLY","success":"One-time transaction binds client, issuer, exact returnTo, state, nonce and S256 challenge","failure":"RETURN_TO_DENIED"},{"id":"AUTH-CN04","method":"GET","path":"/oauth2/authorize","owner":"Identity Platform","browserExposure":"AUTHORIZATION_UI","success":"One-time code issued only for exact client, origin, redirect and challenge","failure":"REDIRECT_URI_MISMATCH"},{"id":"AUTH-CN05","method":"GET","path":"/auth/callback","owner":"Consumer BFF","browserExposure":"CODE_AND_STATE_ONCE","success":"State, issuer, nonce and code verified; server exchanges with S256 verifier","failure":"CALLBACK_TRANSACTION_INVALID"},{"id":"AUTH-CN06","method":"GET","path":"/auth/session","owner":"Consumer BFF","browserExposure":"SAFE_SESSION_PROJECTION","success":"Subject, assurance, expiry and permissions without token-shaped values","failure":"SESSION_EXPIRED"},{"id":"AUTH-CN07","method":"POST","path":"/auth/refresh","owner":"Consumer BFF + Identity","browserExposure":"CSRF_BOUND_COOKIE_ONLY","success":"Refresh family rotates server-side and old handle is burned","failure":"REFRESH_REUSE_DETECTED"},{"id":"AUTH-CN08","method":"POST","path":"/auth/logout","owner":"Consumer BFF + Identity","browserExposure":"CSRF_BOUND_COOKIE_ONLY","success":"Local cookie cleared, refresh family revoked and exact post-logout route used","failure":"LOGOUT_PROPAGATION_FAILED"}],"transactionStates":[{"id":"CREATED","responsibility":"BFF persists a short-lived one-time transaction; no token exists."},{"id":"REDIRECTED","responsibility":"Browser carries only authorization request parameters."},{"id":"AUTHENTICATED","responsibility":"Identity completes primary authentication and consent."},{"id":"CODE_ISSUED","responsibility":"Identity issues a single-use code bound to client, redirect and challenge."},{"id":"CALLBACK_VERIFIED","responsibility":"BFF consumes state, nonce and code exactly once."},{"id":"SESSION_ESTABLISHED","responsibility":"Host-only Secure HttpOnly SameSite=Lax cookie is set."},{"id":"REFRESH_ROTATED","responsibility":"Server-side refresh family advances and prior handle is burned."},{"id":"STEP_UP_REQUIRED","responsibility":"Session remains bounded while a single sensitive action requests higher assurance."},{"id":"REVOKED","responsibility":"Cookie, refresh family and resource access are invalidated."},{"id":"DENIED","responsibility":"Any mismatch terminates the transaction without a fallback Bearer path."}],"errorTaxonomy":["UNREGISTERED_CLIENT","INVALID_ORIGIN","REDIRECT_URI_MISMATCH","PKCE_REQUIRED","PKCE_VERIFIER_MISMATCH","STATE_MISMATCH","NONCE_REPLAY","CODE_REPLAY","SESSION_EXPIRED","REFRESH_REUSE_DETECTED","CSRF_INVALID","STEP_UP_REQUIRED"],"controlSurfaces":[{"id":"AUTH-C01","title":"Client Registry","operator":"Identity Platform","decision":"Compare current registry to exact proposed relying-party contract","realStates":["LOADING","READY","EMPTY","PARTIAL","ERROR","FORBIDDEN","STALE","CONFLICT","SUCCESS"],"status":"TARGET_UI_ONLY"},{"id":"AUTH-C02","title":"Redirect Change Review","operator":"Identity + Security + Consumer","decision":"Review exact origin, callback and post-logout diff before registration","realStates":["LOADING","READY","EMPTY","PARTIAL","ERROR","FORBIDDEN","STALE","CONFLICT","SUCCESS"],"status":"TARGET_UI_ONLY"},{"id":"AUTH-C03","title":"Session Family Inspector","operator":"Security Operations","decision":"Trace rotation, replay and revocation without exposing credentials","realStates":["LOADING","READY","EMPTY","PARTIAL","ERROR","FORBIDDEN","STALE","CONFLICT","SUCCESS"],"status":"TARGET_UI_ONLY"},{"id":"AUTH-C04","title":"Consumer Migration Control","operator":"Program + Consumer Owners + QA","decision":"Advance each repository only with contract, UI-state and negative-test receipts","realStates":["LOADING","READY","EMPTY","PARTIAL","ERROR","FORBIDDEN","STALE","CONFLICT","SUCCESS"],"status":"TARGET_UI_ONLY"}],"migrationLanes":[{"repository":"reits-auth","current":"Origin-only clients, HS256, seven-day TTL","target":"Discovery, JWKS, code+PKCE, exact client registry and durable revocation","owner":"Identity Platform","stage":"WAIT_D05"},{"repository":"miniapp-open-platform","current":"421 handoff plus reits.portal.token","target":"Open Portal BFF with no browser token read API","owner":"Open Platform","stage":"WAIT_D05"},{"repository":"public-booking-platform","current":"Partial cookie plus two localStorage Bearer families","target":"Separate member and merchant BFF sessions and deletion of both fallbacks","owner":"Booking Platform","stage":"WAIT_D05"},{"repository":"opensdk","current":"Go bot Bearer client only","target":"Typed browser start/session/logout/step-up contract without token getter","owner":"Developer Experience","stage":"WAIT_D05"}],"rolloutStages":[{"ordinal":1,"id":"CONTRACT_FREEZE","exit":"Eight contracts, three client registrations and twelve errors approved","status":"WAIT_D05"},{"ordinal":2,"id":"IDENTITY_FOUNDATION","exit":"Discovery, JWKS, code+PKCE and registration tests pass","status":"WAIT_D05"},{"ordinal":3,"id":"OPEN_PORTAL_PILOT","exit":"Nine-state UI and zero-token browser scan pass","status":"WAIT_D05"},{"ordinal":4,"id":"BOOKING_DUAL_MIGRATION","exit":"Member and merchant session families remain isolated","status":"WAIT_D05"},{"ordinal":5,"id":"FALLBACK_DELETION","exit":"All nineteen credential-storage operations deleted and replay suite passes","status":"WAIT_D05"}],"hostileCases":["unknown client","unregistered origin","redirect prefix match","redirect path traversal","plain PKCE","missing verifier","wrong verifier","state mismatch","state replay","nonce replay","code replay","expired transaction","returnTo open redirect","cross-client code swap","cross-origin callback","CSRF missing","CSRF mismatch","refresh reuse","revoked session","merchant/member cookie collision","token in localStorage","token in URL","token in DOM or postMessage","approval principal reuse"],"approvalSeats":[{"role":"IDENTITY_OWNER","decision":"ABSENT"},{"role":"SECURITY_OWNER","decision":"ABSENT"},{"role":"CONSUMER_OWNER","decision":"ABSENT"},{"role":"QA_OWNER","decision":"ABSENT"}],"activationContract":{"d06ActivationAuthorized":false,"clientRegistrationsExecuted":0,"consumerMigrationsExecuted":0,"externalWritesExecuted":0,"ledgerMutationExecuted":false},"invariants":{"programAdvanced":false,"d05RemainsCurrent":true,"productionSecretsStored":0,"browserTokenValuesProjected":0,"sharedEc2QualifiedForD05":false},"boundary":"D06-P1 completes a source-bound control-plane design, contract registry and fail-closed verifier only. It does not register clients, issue credentials, modify consumer repositories, mutate AWS/IAM, advance the program ledger or activate D06."}