[{"data":1,"prerenderedAt":1064},["ShallowReactive",2],{"navigation_docs":3,"-docs-auth-operator-sessions":356,"-docs-auth-operator-sessions-surround":1059},[4,8,34,64,90,139,157,171,193,227,241,266,312,334],{"title":5,"path":6,"stem":7},"Documentation","\u002Fdocs","docs\u002Findex",{"title":9,"path":10,"stem":11,"children":12},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started\u002Findex",[13,14,18,22,26,30],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17},"Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction",{"title":19,"path":20,"stem":21},"Concepts","\u002Fdocs\u002Fgetting-started\u002Fconcepts","docs\u002F01.getting-started\u002F02.concepts",{"title":23,"path":24,"stem":25},"Quickstart (5 minutes)","\u002Fdocs\u002Fgetting-started\u002Fquickstart","docs\u002F01.getting-started\u002F03.quickstart",{"title":27,"path":28,"stem":29},"Local development","\u002Fdocs\u002Fgetting-started\u002Flocal-development","docs\u002F01.getting-started\u002F04.local-development",{"title":31,"path":32,"stem":33},"FAQ","\u002Fdocs\u002Fgetting-started\u002Ffaq","docs\u002F01.getting-started\u002F05.faq",{"title":35,"path":36,"stem":37,"children":38},"Architecture","\u002Fdocs\u002Farchitecture","docs\u002F02.architecture\u002Findex",[39,40,44,48,52,56,60],{"title":35,"path":36,"stem":37},{"title":41,"path":42,"stem":43},"Architecture overview","\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F02.architecture\u002F01.overview",{"title":45,"path":46,"stem":47},"Services","\u002Fdocs\u002Farchitecture\u002Fservices","docs\u002F02.architecture\u002F02.services",{"title":49,"path":50,"stem":51},"Request lifecycle","\u002Fdocs\u002Farchitecture\u002Frequest-lifecycle","docs\u002F02.architecture\u002F03.request-lifecycle",{"title":53,"path":54,"stem":55},"Data model","\u002Fdocs\u002Farchitecture\u002Fdata-model","docs\u002F02.architecture\u002F04.data-model",{"title":57,"path":58,"stem":59},"Status and evidence","\u002Fdocs\u002Farchitecture\u002Fstatus-and-evidence","docs\u002F02.architecture\u002F05.status-and-evidence",{"title":61,"path":62,"stem":63},"Target architecture and authority","\u002Fdocs\u002Farchitecture\u002Ftarget-architecture","docs\u002F02.architecture\u002F06.target-architecture",{"title":65,"path":66,"stem":67,"children":68},"Auth","\u002Fdocs\u002Fauth","docs\u002F03.auth\u002Findex",[69,70,74,78,82,86],{"title":65,"path":66,"stem":67},{"title":71,"path":72,"stem":73},"Overview","\u002Fdocs\u002Fauth\u002Foverview","docs\u002F03.auth\u002F01.overview",{"title":75,"path":76,"stem":77},"Organization and agent model","\u002Fdocs\u002Fauth\u002Forg-project-model","docs\u002F03.auth\u002F02.org-project-model",{"title":79,"path":80,"stem":81},"Issuing API keys","\u002Fdocs\u002Fauth\u002Fissuing-api-keys","docs\u002F03.auth\u002F03.issuing-api-keys",{"title":83,"path":84,"stem":85},"Multi-tenant RLS","\u002Fdocs\u002Fauth\u002Fmulti-tenant-rls","docs\u002F03.auth\u002F04.multi-tenant-rls",{"title":87,"path":88,"stem":89},"Operator sessions and step-up","\u002Fdocs\u002Fauth\u002Foperator-sessions","docs\u002F03.auth\u002F05.operator-sessions",{"title":91,"path":92,"stem":93,"children":94},"Proxy","\u002Fdocs\u002Fproxy","docs\u002F04.proxy\u002Findex",[95,96,99,103,107,111,115,119,123,127,131,135],{"title":91,"path":92,"stem":93},{"title":71,"path":97,"stem":98},"\u002Fdocs\u002Fproxy\u002Foverview","docs\u002F04.proxy\u002F01.overview",{"title":100,"path":101,"stem":102},"Authentication","\u002Fdocs\u002Fproxy\u002Fauthentication","docs\u002F04.proxy\u002F02.authentication",{"title":104,"path":105,"stem":106},"Request routing","\u002Fdocs\u002Fproxy\u002Frequest-routing","docs\u002F04.proxy\u002F03.request-routing",{"title":108,"path":109,"stem":110},"Sessions","\u002Fdocs\u002Fproxy\u002Fsessions","docs\u002F04.proxy\u002F04.sessions",{"title":112,"path":113,"stem":114},"Directives","\u002Fdocs\u002Fproxy\u002Fdirectives","docs\u002F04.proxy\u002F05.directives",{"title":116,"path":117,"stem":118},"Idempotency and budgets","\u002Fdocs\u002Fproxy\u002Fidempotency-and-budgets","docs\u002F04.proxy\u002F06.idempotency-and-budgets",{"title":120,"path":121,"stem":122},"Rate limiting","\u002Fdocs\u002Fproxy\u002Frate-limiting","docs\u002F04.proxy\u002F07.rate-limiting",{"title":124,"path":125,"stem":126},"Provider adapters","\u002Fdocs\u002Fproxy\u002Fprovider-adapters","docs\u002F04.proxy\u002F08.provider-adapters",{"title":128,"path":129,"stem":130},"Auth caching","\u002Fdocs\u002Fproxy\u002Fauth-caching","docs\u002F04.proxy\u002F09.auth-caching",{"title":132,"path":133,"stem":134},"Configuration","\u002Fdocs\u002Fproxy\u002Fconfiguration","docs\u002F04.proxy\u002F10.configuration",{"title":136,"path":137,"stem":138},"Provider routing and resilience","\u002Fdocs\u002Fproxy\u002Fprovider-routing-and-resilience","docs\u002F04.proxy\u002F11.provider-routing-and-resilience",{"title":140,"path":141,"stem":142,"children":143},"Memory","\u002Fdocs\u002Fmemory","docs\u002F05.memory\u002Findex",[144,145,149,153],{"title":140,"path":141,"stem":142},{"title":146,"path":147,"stem":148},"Memory overview","\u002Fdocs\u002Fmemory\u002Foverview","docs\u002F05.memory\u002F01.overview",{"title":150,"path":151,"stem":152},"Write path","\u002Fdocs\u002Fmemory\u002Fwrite-path","docs\u002F05.memory\u002F02.write-path",{"title":154,"path":155,"stem":156},"Search and lifecycle","\u002Fdocs\u002Fmemory\u002Fsearch-and-lifecycle","docs\u002F05.memory\u002F03.search-and-lifecycle",{"title":158,"path":159,"stem":160,"children":161},"Context","\u002Fdocs\u002Fcontext","docs\u002F06.context\u002Findex",[162,163,167],{"title":158,"path":159,"stem":160},{"title":164,"path":165,"stem":166},"Assembly pipeline","\u002Fdocs\u002Fcontext\u002Foverview","docs\u002F06.context\u002F01.overview",{"title":168,"path":169,"stem":170},"Ranking and packing","\u002Fdocs\u002Fcontext\u002Franking-and-packing","docs\u002F06.context\u002F02.ranking-and-packing",{"title":172,"path":173,"stem":174,"children":175},"Intelligence","\u002Fdocs\u002Fintelligence","docs\u002F07.intelligence\u002Findex",[176,177,181,185,189],{"title":172,"path":173,"stem":174},{"title":178,"path":179,"stem":180},"Workers","\u002Fdocs\u002Fintelligence\u002Fworkers","docs\u002F07.intelligence\u002F01.workers",{"title":182,"path":183,"stem":184},"Extraction","\u002Fdocs\u002Fintelligence\u002Fextraction","docs\u002F07.intelligence\u002F02.extraction",{"title":186,"path":187,"stem":188},"Embedder","\u002Fdocs\u002Fintelligence\u002Fembedder","docs\u002F07.intelligence\u002F03.embedder",{"title":190,"path":191,"stem":192},"Extraction evaluation","\u002Fdocs\u002Fintelligence\u002Fevaluation","docs\u002F07.intelligence\u002F04.evaluation",{"title":194,"path":195,"stem":196,"children":197},"API reference","\u002Fdocs\u002Fapi-reference","docs\u002F08.api-reference\u002Findex",[198,199,203,207,211,215,219,223],{"title":194,"path":195,"stem":196},{"title":200,"path":201,"stem":202},"Chat completions","\u002Fdocs\u002Fapi-reference\u002Fchat-completions","docs\u002F08.api-reference\u002F01.chat-completions",{"title":204,"path":205,"stem":206},"Responses","\u002Fdocs\u002Fapi-reference\u002Fresponses","docs\u002F08.api-reference\u002F02.responses",{"title":208,"path":209,"stem":210},"Errors","\u002Fdocs\u002Fapi-reference\u002Ferrors","docs\u002F08.api-reference\u002F03.errors",{"title":212,"path":213,"stem":214},"Health and metrics","\u002Fdocs\u002Fapi-reference\u002Fproxy-health","docs\u002F08.api-reference\u002F04.proxy-health",{"title":216,"path":217,"stem":218},"HTTP route inventory","\u002Fdocs\u002Fapi-reference\u002Fhttp-routes","docs\u002F08.api-reference\u002F05.http-routes",{"title":220,"path":221,"stem":222},"Management API","\u002Fdocs\u002Fapi-reference\u002Fmanagement-api","docs\u002F08.api-reference\u002F06.management-api",{"title":224,"path":225,"stem":226},"Auth gRPC (ValidateToken, ValidateAgent)","\u002Fdocs\u002Fapi-reference\u002Fauth-grpc","docs\u002F08.api-reference\u002F07.auth-grpc",{"title":228,"path":229,"stem":230,"children":231},"MCP","\u002Fdocs\u002Fmcp","docs\u002F09.mcp\u002Findex",[232,233,237],{"title":228,"path":229,"stem":230},{"title":234,"path":235,"stem":236},"Memory server","\u002Fdocs\u002Fmcp\u002Fmemory-server","docs\u002F09.mcp\u002F01.memory-server",{"title":238,"path":239,"stem":240},"Operator gateway","\u002Fdocs\u002Fmcp\u002Foperator-gateway","docs\u002F09.mcp\u002F02.operator-gateway",{"title":242,"path":243,"stem":244,"children":245},"Security","\u002Fdocs\u002Fsecurity","docs\u002F10.security\u002Findex",[246,247,251,254,258,262],{"title":242,"path":243,"stem":244},{"title":248,"path":249,"stem":250},"Security overview","\u002Fdocs\u002Fsecurity\u002Foverview","docs\u002F10.security\u002F01.overview",{"title":100,"path":252,"stem":253},"\u002Fdocs\u002Fsecurity\u002Fauthentication","docs\u002F10.security\u002F02.authentication",{"title":255,"path":256,"stem":257},"Tenant isolation","\u002Fdocs\u002Fsecurity\u002Ftenant-isolation","docs\u002F10.security\u002F03.tenant-isolation",{"title":259,"path":260,"stem":261},"Secrets and keys","\u002Fdocs\u002Fsecurity\u002Fsecrets-and-keys","docs\u002F10.security\u002F04.secrets-and-keys",{"title":263,"path":264,"stem":265},"Prompt injection","\u002Fdocs\u002Fsecurity\u002Fprompt-injection","docs\u002F10.security\u002F05.prompt-injection",{"title":267,"path":268,"stem":269,"children":270},"Operations","\u002Fdocs\u002Foperations","docs\u002F11.operations\u002Findex",[271,272,276,280,284,288,292,296,300,304,308],{"title":267,"path":268,"stem":269},{"title":273,"path":274,"stem":275},"Observability","\u002Fdocs\u002Foperations\u002Fobservability","docs\u002F11.operations\u002F01.observability",{"title":277,"path":278,"stem":279},"Traces and ClickHouse","\u002Fdocs\u002Foperations\u002Ftraces-and-clickhouse","docs\u002F11.operations\u002F02.traces-and-clickhouse",{"title":281,"path":282,"stem":283},"Health checks","\u002Fdocs\u002Foperations\u002Fhealth-checks","docs\u002F11.operations\u002F03.health-checks",{"title":285,"path":286,"stem":287},"Incident response","\u002Fdocs\u002Foperations\u002Fincident-response","docs\u002F11.operations\u002F04.incident-response",{"title":289,"path":290,"stem":291},"Troubleshooting","\u002Fdocs\u002Foperations\u002Ftroubleshooting","docs\u002F11.operations\u002F05.troubleshooting",{"title":293,"path":294,"stem":295},"Billing and budgets","\u002Fdocs\u002Foperations\u002Fbilling-and-budgets","docs\u002F11.operations\u002F06.billing-and-budgets",{"title":297,"path":298,"stem":299},"Evidence and relay","\u002Fdocs\u002Foperations\u002Fevidence-and-relay","docs\u002F11.operations\u002F07.evidence-and-relay",{"title":301,"path":302,"stem":303},"Console","\u002Fdocs\u002Foperations\u002Fconsole","docs\u002F11.operations\u002F08.console",{"title":305,"path":306,"stem":307},"Failure modes and recovery","\u002Fdocs\u002Foperations\u002Ffailure-and-recovery","docs\u002F11.operations\u002F09.failure-and-recovery",{"title":309,"path":310,"stem":311},"Data lifecycle and deletion","\u002Fdocs\u002Foperations\u002Fdata-lifecycle-and-deletion","docs\u002F11.operations\u002F10.data-lifecycle-and-deletion",{"title":313,"path":314,"stem":315,"children":316},"Deployment","\u002Fdocs\u002Fdeployment","docs\u002F12.deployment\u002Findex",[317,318,322,326,330],{"title":313,"path":314,"stem":315},{"title":319,"path":320,"stem":321},"Docker Compose (dev)","\u002Fdocs\u002Fdeployment\u002Fdocker-compose","docs\u002F12.deployment\u002F01.docker-compose",{"title":323,"path":324,"stem":325},"Environment variables","\u002Fdocs\u002Fdeployment\u002Fenvironment-variables","docs\u002F12.deployment\u002F02.environment-variables",{"title":327,"path":328,"stem":329},"Kubernetes","\u002Fdocs\u002Fdeployment\u002Fkubernetes","docs\u002F12.deployment\u002F03.kubernetes",{"title":331,"path":332,"stem":333},"Production readiness","\u002Fdocs\u002Fdeployment\u002Fproduction-readiness","docs\u002F12.deployment\u002F04.production-readiness",{"title":335,"path":336,"stem":337,"children":338},"Reference","\u002Fdocs\u002Freference","docs\u002F13.reference\u002Findex",[339,340,344,348,352],{"title":335,"path":336,"stem":337},{"title":341,"path":342,"stem":343},"Glossary","\u002Fdocs\u002Freference\u002Fglossary","docs\u002F13.reference\u002F01.glossary",{"title":345,"path":346,"stem":347},"Roadmap and gates","\u002Fdocs\u002Freference\u002Froadmap","docs\u002F13.reference\u002F02.roadmap",{"title":349,"path":350,"stem":351},"Architecture decisions","\u002Fdocs\u002Freference\u002Fadr","docs\u002F13.reference\u002F03.adr",{"title":353,"path":354,"stem":355},"Compatibility and versioning","\u002Fdocs\u002Freference\u002Fcompatibility","docs\u002F13.reference\u002F04.compatibility",{"id":357,"title":87,"audience":358,"author":359,"authorUrl":359,"body":360,"coverIndex":359,"coverLabel":359,"coverTone":359,"date":359,"decisionStatus":359,"description":1050,"excerpt":359,"extension":1051,"featured":1052,"historical":1052,"meta":1053,"navigation":1054,"path":88,"readingTime":359,"scope":1055,"seo":1056,"sourceOfTruth":1057,"status":367,"stem":89,"tags":359,"verifiedDate":368,"__hash__":1058},"docs\u002Fdocs\u002F03.auth\u002F05.operator-sessions.md","operator",null,{"type":361,"value":362,"toc":1038},"minimark",[363,369,373,378,389,392,396,411,510,513,517,563,566,578,582,637,640,692,703,707,710,777,787,794,797,905,909,987,991,1005,1009],[364,365],"page-status",{"note":366,"status":367,"verified":368},"Session routes are mounted behind a default-off feature flag; hosted Console integration is not accepted","PROVISIONAL","2026-10-21",[370,371,372],"p",{},"IBEX does not put a PAT in browser storage for Console use. The operator flow exchanges a PAT for short-lived, server-owned cookies, then uses a separate step-up token for actions that need fresh proof. The session machinery is implemented locally; hosted identity, origin, and Console integration remain gated.",[374,375,377],"h2",{"id":376},"flow","Flow",[379,380,386],"pre",{"className":381,"code":383,"language":384,"meta":385},[382],"language-text","PAT → POST \u002Fv1\u002Foperator\u002Fsession\u002Flogin\n    → HttpOnly access cookie\n    → HttpOnly refresh cookie\n    → JS-readable CSRF cookie\n    → POST \u002Frefresh rotates access (and, with Auth, the refresh family)\n    → POST \u002Flogout revokes the session family and clears cookies\n","text","",[387,388,383],"code",{"__ignoreMap":385},[370,390,391],{},"The browser never receives the upstream PAT from these responses, and the API never treats cookie presence alone as authorization.",[374,393,395],{"id":394},"routes","Routes",[370,397,398,399,402,403,406,407,410],{},"All routes are under ",[387,400,401],{},"\u002Fv1\u002Foperator\u002Fsession"," and return ",[387,404,405],{},"503 SERVICE_DEGRADED"," when ",[387,408,409],{},"IBEX_OPERATOR_FEATURE_ENABLED"," is false.",[412,413,414,433],"table",{},[415,416,417],"thead",{},[418,419,420,424,427,430],"tr",{},[421,422,423],"th",{},"Method",[421,425,426],{},"Path",[421,428,429],{},"Input",[421,431,432],{},"Behavior",[434,435,436,458,475,492],"tbody",{},[418,437,438,444,449,455],{},[439,440,441],"td",{},[387,442,443],{},"POST",[439,445,446],{},[387,447,448],{},"\u002Flogin",[439,450,451,452],{},"JSON ",[387,453,454],{},"{ \"pat\": \"ibex_pat_...\" }",[439,456,457],{},"Validates the PAT, issues access\u002Frefresh cookies, sets a CSRF cookie",[418,459,460,464,469,472],{},[439,461,462],{},[387,463,443],{},[439,465,466],{},[387,467,468],{},"\u002Frefresh",[439,470,471],{},"Refresh cookie",[439,473,474],{},"Rotates access; in Auth-owned mode also rotates the refresh token",[418,476,477,481,486,489],{},[439,478,479],{},[387,480,443],{},[439,482,483],{},[387,484,485],{},"\u002Flogout",[439,487,488],{},"Access and\u002For refresh cookie",[439,490,491],{},"Revokes the session family when Auth-owned, then clears cookies",[418,493,494,499,504,507],{},[439,495,496],{},[387,497,498],{},"GET",[439,500,501],{},[387,502,503],{},"\u002Fme",[439,505,506],{},"Access cookie or bearer fallback",[439,508,509],{},"Returns the verified session subject and organization",[370,511,512],{},"Login accepts a PAT in the request body once. Do not persist that PAT in browser storage, URLs, or logs.",[374,514,516],{"id":515},"issuance-modes","Issuance modes",[412,518,519,532],{},[415,520,521],{},[418,522,523,526,529],{},[421,524,525],{},"Environment",[421,527,528],{},"Signing and verification",[421,530,531],{},"Status",[434,533,534,549],{},[418,535,536,539,546],{},[439,537,538],{},"Development",[439,540,541,542,545],{},"HS256 via ",[387,543,544],{},"JWT_HMAC_SECRET","; access 1 hour by default",[439,547,548],{},"Provisional compatibility stub",[418,550,551,554,560],{},[439,552,553],{},"Staging\u002Fproduction",[439,555,556,557],{},"AuthService issues RS256 access\u002Frefresh; API verifies with ",[387,558,559],{},"DASHBOARD_JWT_PUBLIC_KEYS_PEM",[439,561,562],{},"Implemented local path; hosted Console evidence remains open",[370,564,565],{},"AuthService defaults are 15-minute access, 7-day refresh, and 5-minute step-up tokens. The API's development stub has different defaults because it is a local convenience path, not the production issuer. Do not treat the two TTL sets as interchangeable.",[370,567,568,569,573,574,577],{},"The API explicitly does ",[570,571,572],"strong",{},"not"," accept ",[387,575,576],{},"JWT_PRIVATE_KEY_PEM"," as HMAC material. Signing keys stay in AuthService; the API only holds public verification keys.",[374,579,581],{"id":580},"cookies-and-csrf","Cookies and CSRF",[412,583,584,597],{},[415,585,586],{},[418,587,588,591,594],{},[421,589,590],{},"Cookie",[421,592,593],{},"HttpOnly",[421,595,596],{},"Purpose",[434,598,599,612,624],{},[418,600,601,606,609],{},[439,602,603],{},[387,604,605],{},"ibex_session",[439,607,608],{},"Yes",[439,610,611],{},"Short-lived access token",[418,613,614,619,621],{},[439,615,616],{},[387,617,618],{},"ibex_refresh",[439,620,608],{},[439,622,623],{},"Refresh token",[418,625,626,631,634],{},[439,627,628],{},[387,629,630],{},"ibex_csrf",[439,632,633],{},"No; deliberately readable by the Console",[439,635,636],{},"Double-submit CSRF token",[370,638,639],{},"Cookie security is deployment-owned:",[641,642,643,650,675,681],"ul",{},[644,645,646,649],"li",{},[387,647,648],{},"DASHBOARD_COOKIE_SECURE=true"," is required outside development.",[644,651,652,655,656,659,660,663,664,667,668,670,671,674],{},[387,653,654],{},"DASHBOARD_COOKIE_SAMESITE"," is ",[387,657,658],{},"lax",", ",[387,661,662],{},"strict",", or ",[387,665,666],{},"none","; ",[387,669,666],{}," requires ",[387,672,673],{},"Secure",".",[644,676,677,680],{},[387,678,679],{},"DASHBOARD_COOKIE_DOMAIN"," is set only when the UI and API intentionally share a parent domain.",[644,682,683,684,687,688,691],{},"CORS uses an explicit ",[387,685,686],{},"IBEX_ALLOWED_ORIGINS"," allow-list. Credentialed CORS with ",[387,689,690],{},"*"," is rejected.",[370,693,694,695,698,699,702],{},"Cookie-authenticated ",[570,696,697],{},"mutations"," require a matching ",[387,700,701],{},"X-CSRF-Token","; bearer-PAT callers are exempt. Login is CSRF-exempt because it establishes the session.",[374,704,706],{"id":705},"totp-and-step-up","TOTP and step-up",[370,708,709],{},"AuthService owns the TOTP primitives:",[412,711,712,721],{},[415,713,714],{},[418,715,716,719],{},[421,717,718],{},"RPC",[421,720,596],{},[434,722,723,737,747,757,767],{},[418,724,725,730],{},[439,726,727],{},[387,728,729],{},"BeginTotpEnrollment",[439,731,732,733,736],{},"Start enrollment and return an ",[387,734,735],{},"otpauth:\u002F\u002F"," URI",[418,738,739,744],{},[439,740,741],{},[387,742,743],{},"ConfirmTotpEnrollment",[439,745,746],{},"Confirm enrollment with a code",[418,748,749,754],{},[439,750,751],{},[387,752,753],{},"CreateStepUpToken",[439,755,756],{},"Verify TOTP and mint a short-lived step-up JWT",[418,758,759,764],{},[439,760,761],{},[387,762,763],{},"IssueOperatorSession",[439,765,766],{},"Mint RS256 access\u002Frefresh JWTs for an authenticated caller",[418,768,769,774],{},[439,770,771],{},[387,772,773],{},"RevokeOperatorSession",[439,775,776],{},"Invalidate the session and its refresh family",[370,778,779,780,783,784,786],{},"TOTP is disabled by default (",[387,781,782],{},"IBEX_AUTH_TOTP_ENABLED=false","). When enabled, AuthService requires ",[387,785,576],{},", JWT issuer\u002Faudience, and Redis so TOTP attempt lockouts are shared across replicas. TOTP secrets are sealed with the credentials master key.",[370,788,789,790,793],{},"High-impact API actions can require ",[387,791,792],{},"X-IBEX-Step-Up",". The proof must bind to the same organization, subject, and session, and AuthService consumes the step-up JTI before the mutation so replay fails. Missing, expired, wrong-org, or replayed proof is denied without leaking whether the target exists. This is an implemented seam, not evidence that every privileged Console action has an accepted UI and audit flow.",[374,795,132],{"id":796},"configuration",[412,798,799,808],{},[415,800,801],{},[418,802,803,806],{},[421,804,805],{},"Variable",[421,807,596],{},[434,809,810,819,833,849,858,867,876,886,895],{},[418,811,812,816],{},[439,813,814],{},[387,815,409],{},[439,817,818],{},"Kill switch for operator session and SSE routes; default false",[418,820,821,830],{},[439,822,823,826,827],{},[387,824,825],{},"JWT_ISSUER"," \u002F ",[387,828,829],{},"JWT_AUDIENCE",[439,831,832],{},"Session claim validation",[418,834,835,846],{},[439,836,837,826,840,826,843],{},[387,838,839],{},"JWT_ACCESS_TOKEN_TTL",[387,841,842],{},"JWT_REFRESH_TOKEN_TTL",[387,844,845],{},"JWT_STEP_UP_TOKEN_TTL",[439,847,848],{},"AuthService-issued TTLs",[418,850,851,855],{},[439,852,853],{},[387,854,576],{},[439,856,857],{},"AuthService RS256 signing key; never given to the API",[418,859,860,864],{},[439,861,862],{},[387,863,559],{},[439,865,866],{},"API verification key set",[418,868,869,873],{},[439,870,871],{},[387,872,544],{},[439,874,875],{},"Development-only provisional HS256 material",[418,877,878,883],{},[439,879,880],{},[387,881,882],{},"DASHBOARD_CSRF_SECRET",[439,884,885],{},"CSRF double-submit key; required outside development",[418,887,888,892],{},[439,889,890],{},[387,891,686],{},[439,893,894],{},"Exact Console origin allow-list",[418,896,897,902],{},[439,898,899],{},[387,900,901],{},"IBEX_AUTH_TOTP_ENABLED",[439,903,904],{},"Enables TOTP and step-up RPCs",[374,906,908],{"id":907},"failure-behavior","Failure behavior",[412,910,911,921],{},[415,912,913],{},[418,914,915,918],{},[421,916,917],{},"Condition",[421,919,920],{},"Result",[434,922,923,933,943,953,962,970,978],{},[418,924,925,928],{},[439,926,927],{},"Operator feature disabled",[439,929,930,932],{},[387,931,405],{}," before route logic",[418,934,935,938],{},[439,936,937],{},"Invalid\u002Frevoked PAT at login",[439,939,940],{},[387,941,942],{},"401 INVALID_TOKEN",[418,944,945,948],{},[439,946,947],{},"AuthService unavailable during login\u002Frefresh",[439,949,950,952],{},[387,951,405],{},"; do not fall back to unsigned cookies",[418,954,955,958],{},[439,956,957],{},"Missing refresh cookie",[439,959,960],{},[387,961,942],{},[418,963,964,967],{},[439,965,966],{},"Access and refresh proofs bind different sessions",[439,968,969],{},"Logout fails closed and clears cookies",[418,971,972,975],{},[439,973,974],{},"Step-up missing, stale, replayed, or wrong subject",[439,976,977],{},"Deny; no mutation",[418,979,980,983],{},[439,981,982],{},"Public keys missing outside development",[439,984,985],{},[387,986,405],{},[374,988,990],{"id":989},"what-remains-open","What remains open",[641,992,993,996,999,1002],{},[644,994,995],{},"Console login, enrollment, invites, and mutation UI are not accepted.",[644,997,998],{},"Hosted AuthService\u002Fsession topology, deployment origin, and credentialed CORS\u002FCSRF evidence are incomplete.",[644,1000,1001],{},"Two-tenant negative tests, session revocation drills, and rollback runbooks are still required for hosted promotion.",[644,1003,1004],{},"The development HS256 path is a compatibility stub and must not become the production issuer.",[374,1006,1008],{"id":1007},"related","Related",[641,1010,1011,1018,1023,1028,1033],{},[644,1012,1013,1017],{},[1014,1015,1016],"a",{"href":72},"Auth overview"," — identity plane and permissions",[644,1019,1020,1022],{},[1014,1021,79],{"href":80}," — PAT creation and rotation",[644,1024,1025,1027],{},[1014,1026,220],{"href":221}," — route families that consume sessions",[644,1029,1030,1032],{},[1014,1031,301],{"href":302}," — presentation and live-read boundary",[644,1034,1035,1037],{},[1014,1036,259],{"href":260}," — key ownership and rotation",{"title":385,"searchDepth":1039,"depth":1039,"links":1040},2,[1041,1042,1043,1044,1045,1046,1047,1048,1049],{"id":376,"depth":1039,"text":377},{"id":394,"depth":1039,"text":395},{"id":515,"depth":1039,"text":516},{"id":580,"depth":1039,"text":581},{"id":705,"depth":1039,"text":706},{"id":796,"depth":1039,"text":132},{"id":907,"depth":1039,"text":908},{"id":989,"depth":1039,"text":990},{"id":1007,"depth":1039,"text":1008},"How Console and management routes exchange a PAT for a server-owned session, verify it, and require fresh proof for high-impact actions.","md",false,{},true,"provisional",{"title":87,"description":1050},"services\u002Fapi\u002Fapp\u002Frouters\u002Fsession.py; services\u002Fauth\u002Finternal\u002Fgrpc\u002Ftotp_session.go; engineering\u002Fadr\u002F0078-operator-runtime-topology.md; engineering\u002Fadr\u002F0079-operator-session-rs256-totp.md","0LeElHYEiXMAEpQpKui25cCsJa8Gq71jT6JUXxoRZWo",[1060,1062],{"title":83,"path":84,"stem":85,"description":1061,"children":-1},"Row-level security policies isolating tenant data in Postgres.",{"title":91,"path":92,"stem":93,"description":1063,"children":-1},"The authenticated HTTP edge for chat completions, Responses, directives, sessions, and provider routing.",1792875074468]