stacklok / stacklok/mecatl

feat(driver): enforce caller ownership for remote stores (B-lite)

Open
#452 0 comments 0 reactions 1 assignee View on GitHub

@jhrozek is already working on this.

Since Aug 11, 2026.

enhancement
Dominant language
Go
Stars
152
Forks
16
Avg merge
14h 48m
Merged PRs (30d)
536

Description

Driver-side enforcement is the B-lite follow-up to #368. It closes the explicitly documented trusted-driver boundary only after #368 has established caller ownership and application-side enforcement.

Depends on #368. Linked from the #367 caller-identity spike.

Decision record

  • The driver receives a principal claim only: identity, never bearer tokens, scopes, or delegated authority.
  • The claim travels as exactly one binary protobuf gRPC metadata value and is parsed once by driver middleware.
  • The driver accepts a claim only from the authenticated mecatl workload: explicit allowed mTLS client identity or Unix peer identity. Test-only construction may accept any peer issued by the dedicated test CA; production configuration may not.
  • The application injects the claim from the real session.Principal in a context-aware driver-client wrapper. A nil caller remains absent; no anonymous principal is minted.
  • Caller-owned operations and global maintenance are separate driver surfaces. Maintenance is authenticated as the workload but cannot invoke ordinary caller-owned operations.
  • Ownership mismatch, a non-owned parent, and absent resources all appear as NotFound. Invalid/missing claims and unauthenticated peers remain authentication/protocol failures.
  • The driver has an explicit trusted or enforced mode. Enforcement is never inferred from metadata presence. When #368 caller enforcement is enabled, the application must fail startup if a relevant remote driver does not advertise enforced ownership capability.
  • One private durable OwnershipRegistry is injected into all driver handlers. It is not a public RPC service. It records immutable ownership before the payload is published and is used for parent resolution (event log → session; fire → schedule).
  • Session and schedule registry keys use (resource kind, opaque server-minted cryptographically random ID). Memory uses driver-derived keys: (issuer, subject, logical key) and, for project memory, (workspace root digest, issuer, subject, logical key).
  • The project-memory workspace namespace is SHA-256 of the canonical server-resolved workspace root. It is automatic, does not cross the driver as a path, and is not caller/model input.
  • Delete atomically removes the live payload and registry entry. IDs are always freshly server-minted; tombstones and migration are deliberately out of scope.
  • Existing unregistered driver data is not migrated. Enforced mode treats it as absent.

Acceptance criteria

  • Enforced driver endpoints authenticate the workload peer before accepting a caller claim; arbitrary CA peers cannot assert identities in production.
  • Every caller-owned driver RPC requires one valid principal claim and applies the same ownership decision semantics as #368.
  • Every global/maintenance operation has an explicitly classified infrastructure surface; it cannot be reached through the caller-owned API.
  • Driver reads, writes, deletes, lists, event-log access, memory access, schedule execution, and parent-derived access use the one injected ownership registry.
  • A resource is never observable through an enforced driver without a preceding immutable registry entry. Same-owner create retries work; a different owner cannot learn an ID collision.
  • Alice and Bob may use the same logical user/project-memory key without sharing data. Project memory additionally separates workspace-root digests.
  • Owner mismatch is externally indistinguishable from missing data, including through parent-derived event/fire operations.
  • Missing, duplicate, malformed, or unauthorized claims fail closed and are distinguishable only as protocol/authentication failures, not ownership disclosures.
  • No bearer token, token-derived authority, scope, or raw workspace path crosses the driver protocol.
  • The application refuses to start caller-enforced remote-store configuration against a trusted/non-capable driver; non-OIDC deployments retain explicitly declared trusted-driver compatibility.
  • Enforced mode does not access legacy driver records without registry ownership; there is no lazy adoption or migration path.
  • Driver conformance/negative tests cover direct driver calls, missing/forged claims, another owner’s resources, list filtering, derived parent resources, system maintenance isolation, and test-only peer relaxation.

Proof scenarios

  • A direct driver client authenticated as the allowed workload but claiming Bob cannot load, update, delete, list, or stream Alice-owned session/event/memory/schedule resources; each ownership miss is NotFound.
  • A client with a valid certificate from an unrelated CA-issued workload cannot submit any caller claim to an enforced production driver.
  • Alice and Bob store the same user-memory and project-memory logical keys and later retrieve only their own values.
  • A scheduler maintenance operation finds due work through its infrastructure surface, while a caller-owned endpoint cannot enumerate other owners’ schedules.
  • A missing claim cannot silently fall back to trusted behavior in an enforced driver.
  • A pre-B-lite record without a registry entry is absent after enforcement cutover and cannot be claimed by the first caller.

Non-goals

  • End-user bearer-token forwarding or per-driver IdP/JWKS validation.
  • Driver-side authorization policy/scopes.
  • Migration or lazy adoption of pre-enforcement records.
  • Reusable caller-supplied session/schedule IDs.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.