fix: enforce installed HTTP auth profiles
Install the REST auth profile registry once at composition and make it the single transport authority for V3. Contract composition now rejects an unregistered authProfileId, so the executor never resolves a profile at runtime. The credential collaborator contributes proof headers only: Fetch credentials come from the resolved profile, transport-owned and forbidden headers are rejected, headers outside the profile's allowed set are rejected, and a missing required header fails closed as AUTH_INTEGRATION_FAILURE with zero fetch calls. The final invariant re-proves credentials mode and the exact header sets. Demo mode satisfies the strict bearer profile with a fixed non-secret marker instead of weakening REFERENCE_EXTERNAL_BEARER. Credential owners now receive the operation lifetime through AuthOperationContext. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
67cc5b6d2c
commit
4e87bacdf3
@@ -262,6 +262,39 @@ auth-required operation은 session state가 `authenticated`가 아니면 fetch
|
||||
`integration-failed`, `unauthenticated`와 credential attach rejection을 anonymous
|
||||
request로 downgrade하지 않는다.
|
||||
|
||||
#### 5-1. Installed auth profile registry (V3 집행)
|
||||
|
||||
`installRestAuthProfileRegistry()`가 composition 시점에 profile을 한 번 설치하고
|
||||
`INSTALLED_REST_AUTH_PROFILES`가 유일한 authority다. contract composition
|
||||
(`assertExecutionPolicy`)은 등록되지 않은 `authProfileId`를 거절하므로 executor는
|
||||
runtime에 profile을 발명하지 않는다. profile은 다음을 exact하게 소유한다.
|
||||
|
||||
- Fetch `credentials` (credential collaborator가 바꿀 수 없다)
|
||||
- `allowedCredentialHeaders`: 이 operation이 허용하는 정확한 proof header 집합
|
||||
- `requiredCredentialHeaders`: dispatch 전에 반드시 관찰되어야 하는 집합
|
||||
|
||||
`CredentialPatchOutcome.READY`는 proof header만 담는다. `credentials` field는
|
||||
제거되었다. credential owner가 transport-owned header(`accept`, `content-type`,
|
||||
`idempotency-key`)나 forbidden header를 넣거나, profile이 허용하지 않는 header를
|
||||
넣거나, required header를 빠뜨리면 `AUTH_INTEGRATION_FAILURE`이고 fetch 0회이며
|
||||
command effect는 `NOT_STARTED`다. `idempotency-key`는 contract-owned이므로 더
|
||||
구체적인 `UNEXPECTED_IDEMPOTENCY_KEY` request violation으로 남는다.
|
||||
`UNAUTHENTICATED`는 user/session state이지 integration failure가 아니다.
|
||||
|
||||
transport-owned header는 credential header 뒤에 기록되어 key ordering으로도
|
||||
shadow될 수 없고, final invariant가 `init.credentials`와 profile을 다시 대조하며
|
||||
allowed/required credential header 집합을 독립적으로 재검증한다.
|
||||
|
||||
`AUTH_MODE=demo`는 profile을 약화시키지 않는다. `createDemoSessionAdapter`가
|
||||
고정된 비밀 아닌 `DEMO_AUTHORIZATION_MARKER` proof header를 제공하여 strict
|
||||
`REFERENCE_EXTERNAL_BEARER`를 그대로 만족시킨다. 진짜 anonymous backend는 별도
|
||||
anonymous contract/profile을 composition에서 선택해야 한다.
|
||||
|
||||
credential collaborator는 `AuthOperationContext { signal, deadlineAtMonotonicMs }`를
|
||||
받는다. cooperative owner는 스스로 중단하고, non-cooperative owner도 executor가
|
||||
같은 lifetime signal과 race하므로 operation 수명을 넘기지 못하며 late completion은
|
||||
관찰되지 않는다.
|
||||
|
||||
### 6. Cookie auth, CSRF와 CORS
|
||||
|
||||
same-origin BFF cookie session을 기본 권장한다.
|
||||
|
||||
Reference in New Issue
Block a user