Skip to content

Commit b623d60

Browse files
committed
fix(service-storage): the family gate and the route judge the same credential
The storage family's ADR-0069 gate now judges every credential a route of the family can serve, so a session the policy holds is refused on every route of the family whatever else the request carries. A held key is still refused with its owner's posture through the shared key-admission seam. Claude-Session: https://claude.ai/code/session_01Nk17Z26X5DB59iQztDBADH Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5da2e88 commit b623d60

1 file changed

Lines changed: 18 additions & 14 deletions

File tree

‎packages/services/service-storage/src/storage-service-plugin.ts‎

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,12 +1248,15 @@ function resolveGateAuthService(registry: StorageGateRegistry): RequestAuthServi
12481248
* KEY's answer, from the shared key-admission seam (`resolveApiKeyAdmission`)
12491249
* with the auth service's per-user posture computation: a key whose owner
12501250
* holds an `account`-scope posture answers that posture, and the door refuses
1251-
* it with the session's `403`; an admitted key answers no posture, and the
1252-
* session is NOT read for it — a cookie beside a key never answers for the
1253-
* key. A key the seam does not recognise (`none`) leaves the session's own
1254-
* gate to answer, exactly as the identity resolution falls through to the
1255-
* session for it. Asked with the door's tenancy posture, so a key the posture
1256-
* refuses is refused before its owner is asked, as on every other face.
1251+
* it with the session's `403`. Asked with the door's tenancy posture, so a key
1252+
* the posture refuses is refused before its owner is asked, as on every other
1253+
* face.
1254+
*
1255+
* [#24366] The family gate and the route judge the same credential: the gate
1256+
* judges every credential a route of this family can serve, so a session the
1257+
* policy holds is refused on every route whatever else the request carries.
1258+
* One door fronts every route, so the seam's answer about a key never stands
1259+
* in for the session's own posture.
12571260
*/
12581261
function buildAuthGateSessionReader(
12591262
registry: StorageGateRegistry,
@@ -1284,12 +1287,12 @@ function buildAuthGateSessionReader(
12841287
await resolveAdmissionTenancyPosture(registry),
12851288
userAuthGateSourceOf(auth),
12861289
// [#23367] The API-key lifecycle policy, from the same service. A key
1287-
// its own lifecycle refuses (`lifecycle`) carries no posture and is
1288-
// left to the identity resolution below, which fails it closed.
1290+
// its own lifecycle refuses (`lifecycle`) carries no posture; the
1291+
// route that would serve it fails it closed.
12891292
apiKeyLifecyclePolicySourceOf(auth),
12901293
);
12911294
if (admission.outcome === 'held') return { authGate: admission.gate };
1292-
if (admission.outcome !== 'none') return undefined;
1295+
// [#24366] Every other answer falls through to the session's own gate.
12931296
}
12941297
let session: SessionRead | null;
12951298
try {
@@ -1468,11 +1471,12 @@ function buildFileReadAuthorizer(
14681471
// behind the family's door (`mountFamilyRoute` in
14691472
// `storage-routes.ts`), whose gate reader
14701473
// (`buildAuthGateSessionReader`) has already refused a held session
1471-
// or a held owner's key on this request with the posture's `403`, and
1472-
// both are bound by `composeStorageRoutes` from the same `auth`
1473-
// service. The context the door hands on stays truthful (a held
1474-
// principal carries the `authGate` decided off the read that admitted
1475-
// it) without a second read: `'reread-when-active'` would read the
1474+
// or a held owner's key on this request with the posture's `403`,
1475+
// whatever else the request carries (#24366), and both are bound by
1476+
// `composeStorageRoutes` from the same `auth` service. The context
1477+
// the door hands on stays truthful (a held principal carries the
1478+
// `authGate` decided off the read that admitted it) without a second
1479+
// read: `'reread-when-active'` would read the
14761480
// session a third time on this request and add an outage arm no
14771481
// caller of this door ever had.
14781482
// - `credentials: 'api-key-and-session'`: the headers are the real

0 commit comments

Comments
 (0)