Skip to content

feat(auth): introduce typed AuthContext contract across the stack#411

Merged
ngalluzzo merged 3 commits intomainfrom
typed-auth-context
Mar 5, 2026
Merged

feat(auth): introduce typed AuthContext contract across the stack#411
ngalluzzo merged 3 commits intomainfrom
typed-auth-context

Conversation

@ngalluzzo
Copy link
Owner

@ngalluzzo ngalluzzo commented Mar 5, 2026

Summary

  • Closes the JsonObject gap: authContext was typed as JsonObject at every contract boundary — dispatch requests, credential-store I/O, kernel contracts, app-runtime-facade-contracts, and runtime internals. It is now typed as AuthContext (from new host-contracts/src/auth-context/) everywhere, consistent with how PrincipalContext was already handled.
  • Adds surface-boundary validation: load-credential-context.ts now calls authContextSchema.safeParse() on the value returned from a credential store's load, mirroring the existing principalInput validation — failing closed or degrading to anonymous per the configured policy.
  • Eliminates the expresso-std blind cast: getAuthContext() previously returned auth as AuthContext with no verification. It now uses authContextSchema.safeParse(auth) and returns undefined on failure, making policy operator failures explicit rather than silently incorrect.

What changed

Layer Change
host-contracts/src/auth-context/ NewauthContextSchema (Zod, .passthrough()), AuthContext type, parseAuthContext, authContextContracts barrel
surface-contracts credential-store schemas jsonObjectSchemaauthContextSchema
surface-contracts credential-store types Remove Omit<…, "authContext"> & { authContext?: JsonObject } override on 5 types
surface-contracts dispatch request authContextSchema.optional() + DispatchRequest.authContext?: AuthContext
kernel-contracts entrypoint-runtime + semantic-engine authContext?: AuthContext
app-runtime-facade-contracts create + subscribe 3 Zod schemas + AppRuntimeInteractionSessionWriteInput interface
surface-adapters/load-credential-context.ts Add safeParse validation block after principal validation
kernel-runtime/entrypoint/types.ts + domain-runtime/execution-core/context.ts authContext?: AuthContext
expresso-std/auth/auth-helpers.ts Remove local interface, import from host-contracts, replace cast with safeParse
All 4 credential-store payload files Schema fields + helper signatures use AuthContext
Conformance fixtures unknown[](AuthContext | undefined)[]

Test plan

  • Workspace typecheck: bun run typecheck — all 75 packages pass
  • Auth-context conformance suite: bun test products/quality/conformance/test/credential-store-auth-context-*.test.ts — all 4 tests pass
  • Verify getAuthContext() in expresso-std returns undefined for objects that don't match any known AuthContext fields (regression: previously would cast and return them)
  • Verify a credential store returning a malformed authContext (e.g. { roles: "not-an-array" }) is rejected at the surface boundary under fail_closed policy and degraded under degrade_to_anonymous
  • Smoke test an existing surface (HTTP or web) with a full sign-in flow to confirm authContext still propagates end-to-end

Notes

  • authContextSchema uses .passthrough() intentionally — JWT payloads commonly include aud, iss, jti and other standard claims not enumerated in our schema. Extra fields are preserved, not stripped.
  • credentialState on the credential-store types was left as JsonObject — it is genuinely freeform state that varies per store implementation and has no shared semantics across the system.

Issue Link

No linked issues detected from commit messages.

Promote AuthContext from an opaque JsonObject pass-through to a
first-class typed contract in host-contracts, propagated consistently
through every layer that previously used JsonObject as a placeholder.

- Add host-contracts/src/auth-context/ with Zod schema (.passthrough()),
  AuthContext type, parseAuthContext, and authContextContracts
- Replace jsonObjectSchema with authContextSchema in all credential-store
  schemas (load output, save input/output, clear input/output)
- Simplify credential-store types by removing the Omit/JsonObject override
  for authContext; credentialState override retained
- Update DispatchRequest, kernel-contracts entrypoint-runtime and
  semantic-engine, app-runtime-facade-contracts invoke/subscribe schemas
  and AppRuntimeInteractionSessionWriteInput
- Add authContextSchema.safeParse() validation at the surface boundary in
  load-credential-context.ts, symmetric with existing principal validation;
  respects fail_closed / degrade_to_anonymous policy
- Update runtime types: kernel-runtime/entrypoint/types.ts,
  domain-runtime/execution-core/context.ts
- Remove local AuthContext interface from expresso-std auth-helpers.ts;
  import from host-contracts and replace blind cast with safeParse
- Update all four credential-store payload files (cookie, redis, memory,
  local-storage) to use AuthContext
- Tighten conformance fixture types from unknown[] to
  (AuthContext | undefined)[]
- Full workspace typecheck passes; all authContext conformance tests pass
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f07ef3920f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ngalluzzo ngalluzzo merged commit 07e5920 into main Mar 5, 2026
8 of 11 checks passed
@ngalluzzo ngalluzzo deleted the typed-auth-context branch March 5, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant