credentialfence

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package credentialfence is the sealed source of the credential-invalidation FenceToken — a capability proof that authorizes calls to the three credential mutation methods (session.Store.RevokeForSubject / refresh.Store.RevokeUser / ports.UserRepository.BumpAuthzEpoch).

Why

Before #1033 the credential-invalidate funnel was half-closed:

  • DOWNSTREAM Hard — the three mutation methods' caller allowlist is locked by archtests CREDENTIAL-INVALIDATE-FUNNEL-01 / USER-AUTHZ-EPOCH-BUMP-FUNNEL-01 / REFRESH-REVOKE-USER-FUNNEL-01 (ResolveMethodCall form-uniqueness).
  • UPSTREAM Soft — any package could construct the receivers and call the methods directly. Only CI-time archtest catches it; Go's type system did not.

042 §3a row 3 and §4 ROI row 2 flagged this as the single remaining structural opening in the revocation safety model. This package closes it: the three mutation methods now require a FenceToken argument that only Mint can produce.

How

FenceToken is a sealed interface — the unexported isCredentialFenceToken marker method makes external implementations impossible at compile time (Go visibility rule: only types declared in this package can implement an interface with an unexported method). The concrete impl [fenceToken] is unexported, so [fenceToken{}] cannot be constructed from outside the package either.

Mint is the sole constructor. Its callers are restricted by archtest FENCE-TOKEN-MINT-FUNNEL-01 to:

  • cells/accesscore/internal/credentialinvalidate/ — the production funnel
  • runtime/auth/session/storetest/ + runtime/auth/refresh/storetest/ + cells/accesscore/internal/ports/conformance/ — conformance suites that must exercise the contract end-to-end
  • *_test.go files in any package — unit tests for impls and stubs

Any other caller is detected as a form-uniqueness violation and fails CI.

AI-robust evaluation

Three mechanisms with distinct enforcement layers — do not collapse them into one "Hard":

  • Construction seal — Hard, compile-time (Go type system). FenceToken is unimplementable outside this package (unexported marker method) and the concrete [fenceToken] is unexported, so no external composite literal can build one. This is the only compile-time guarantee here; it forces every external would-be revoker to obtain a token from Mint.
  • Mint callsite funnel — Hard via call-site form-uniqueness, archtest-bound (FENCE-TOKEN-MINT-FUNNEL-01), NOT compile-time. The scanner is form-complete: it flags every reference to Mint (direct call, function-value capture, return, pass-through arg, reflect arg) via a ResolvePackageRef SelectorExpr walk, so there is no per-form blindspot self-check to drift. Go cannot express "only package X may call Mint", so this is the Hard ceiling the rule's shape can reach (the PANIC-REGISTERED-01 precedent).
  • nil-FenceToken — runtime backstop, NOT a static grade. A literal nil argument compiles and is invisible to the two static mechanisms above; MustHave in each mutation impl converts it to an immediate panic (pkg/validation.IsNilInterface → errcode.Assertion via panicregister.Approved → 500). Defense-in-depth; it does not elevate any static grade.

Combined grade: funnel upstream Hard, downstream Hard — resting on the construction seal (compile-time) plus the two form-complete archtest funnels. The nil guard is a runtime backstop, not part of the static claim. See .claude/rules/gocell/ai-robust.md §"Hard 范本目录" entry "typed marker funnel for unbounded ops" and §"Funnel 双向锁评级".

Reference precedent

  • kernel/outbox/cell_marker.go (CellPublisher / CellEmitter sealed marker pattern)
  • kernel/persistence/cell_marker.go (CellTxManager sealed marker pattern)
  • pkg/panicregister/panicregister.go (typed marker funnel + PANIC-REGISTERED-01 archtest form-uniqueness)

Audit / plan references

  • docs/reviews/202605181109-042-archtest-six-agent-audit.md §3a row 3, §4 ROI row 2
  • docs/plans/202605191100-043-archtest-audit-and-capability-gap-parallel-plan.md §1 row 4
  • docs/architecture/202605101400-adr-credential-session-protocol.md §A16 (credential-invalidate sealed FenceToken — 上游 funnel 闭环)

Open-source comparison: HashiCorp Vault audit broker sealed token, crypto/tls.Config sealed fields.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MustHave

func MustHave(tok FenceToken, site string)

MustHave panics through the panic-taxonomy funnel (panicregister.Approved + errcode.Assertion, B-class) when tok is nil or a typed-nil interface, surfacing the programmer error as a 500 via the kernel Recovery middleware rather than letting the bug slip past as a silent failure deeper in the call chain.

site identifies the offending method for the panic message — pass a const string such as "session.Store.RevokeForSubject" so the operator can pinpoint the bypass at a glance.

The three credential-mutation methods (session.Store.RevokeForSubject, refresh.Store.RevokeUser, ports.UserRepository.BumpAuthzEpoch) and their implementations call MustHave as the first statement of their bodies. This is the defense-in-depth complement to the type-system seal — even if a future call form bypasses the upstream archtest blindspot checks (function-value capture, reflect.MethodByName), a nil token would still produce a hard failure here.

MustHave is package-public because it is called from impl packages (runtime/auth/session, runtime/auth/refresh, cells/accesscore/internal/mem, adapters/postgres, adapters/redis); it does not weaken the seal because it cannot construct a FenceToken — only Mint can.

Types

type FenceToken

type FenceToken interface {
	// contains filtered or unexported methods
}

FenceToken is a sealed capability proof for the credential-invalidation trifecta. The unexported isCredentialFenceToken marker method makes this interface unimplementable outside the credentialfence package, so external packages cannot construct a non-nil FenceToken value.

Allowed call site for Mint is enforced by archtest FENCE-TOKEN-MINT-FUNNEL-01 (see package godoc).

func Mint

func Mint() FenceToken

Mint returns a fresh FenceToken. It is the sole entry point for constructing a non-nil FenceToken value.

Allowed callers (enforced by archtest FENCE-TOKEN-MINT-FUNNEL-01):

  • cells/accesscore/internal/credentialinvalidate/ (the production funnel)
  • runtime/auth/session/storetest/, runtime/auth/refresh/storetest/, cells/accesscore/internal/ports/conformance/ (conformance suites)
  • any *_test.go file (unit / integration test bodies)

Any other caller is rejected as a form-uniqueness violation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL