Documentation
¶
Overview ¶
Package accesscore implements the accesscore Cell: identity management, session lifecycle (login/refresh/logout/validate), RBAC authorization, and role queries.
cell_providers.go hosts AccessCore's "exposed service" provider methods — accessors that other layers (runtime/auth middleware) consume to wire cross-cutting concerns. Routing, event subscription, health probe, and lifecycle wiring now live in cell_init.go (Batch 3 Registry migration). Constructor + options live in cell.go; Init() + slice construction in cell_init.go.
Index ¶
- Constants
- type AccessCore
- type Option
- func WithBootstrapAuth(mw func(http.Handler) http.Handler) Option
- func WithCASProtocol(p *cas.Protocol) Option
- func WithClock(clk clock.Clock) Option
- func WithConfigEventCollector(collector obmetrics.ConfigEventCollector) Option
- func WithConfigGetter(c ports.ConfigGetter) Option
- func WithCursorCodec(codec *query.CursorCodec) Option
- func WithEmitter(e outbox.Emitter) Option
- func WithInMemoryDefaults() Option
- func WithJWTIssuer(issuer *auth.JWTIssuer) Option
- func WithJWTVerifier(verifier *auth.JWTVerifier) Option
- func WithLogger(l *slog.Logger) Option
- func WithMetricsProvider(p metrics.Provider) Option
- func WithOutboxDeps(pub outbox.CellPublisher, writer outbox.CellWriter) Option
- func WithRefreshGC(interval, retention time.Duration) Option
- func WithRefreshStore(store refresh.Store) Option
- func WithRoleRepository(r ports.RoleRepository) Option
- func WithSessionRepository(r ports.SessionRepository) Option
- func WithSetupLock(lock ports.SetupLock) Option
- func WithTxManager(tx persistence.CellTxManager) Option
- func WithUserRepository(r ports.UserRepository) Option
Constants ¶
const PasswordVersionField = "password_version"
PasswordVersionField is the DB column name used as the CAS version field for ChangePassword optimistic-concurrency control. Composition root uses this constant when wiring cas.Protocol for the user table:
cas.MustNewProtocol(cas.WithVersionField(accesscore.PasswordVersionField))
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccessCore ¶
AccessCore is the accesscore Cell implementation. +cell:listener:ref=cell.PrimaryListener,prefix=/api/v1/access +cell:listener:ref=cell.InternalListener,prefix=/internal/v1/access
func NewAccessCore ¶
func NewAccessCore(opts ...Option) *AccessCore
NewAccessCore creates a new AccessCore Cell.
func (*AccessCore) Authorizer ¶
func (c *AccessCore) Authorizer() auth.Authorizer
Authorizer returns the authorization-decide service (implements auth.Authorizer).
func (*AccessCore) TokenVerifier ¶
func (c *AccessCore) TokenVerifier() auth.IntentTokenVerifier
TokenVerifier returns the session-validate service. It satisfies auth.IntentTokenVerifier so it can be plugged into AuthMiddleware without a runtime type assertion.
type Option ¶
type Option func(*AccessCore)
Option configures an AccessCore Cell.
func WithBootstrapAuth ¶
WithBootstrapAuth injects the per-route replacement authentication middleware for the admin setup endpoint (POST /api/v1/access/setup/admin).
The composition root passes runtime/auth.NewBootstrapMiddleware so that the endpoint is gated by Basic Auth credentials from GOCELL_BOOTSTRAP_ADMIN_* env vars (D5: env creds authenticate the operator; request body defines the admin identity). This applies in both bootstrap and interactive modes — the operator Basic Auth credential (ADR §D2) makes the protection a permanent requirement, not an interactive-only feature.
REQUIRED: Init() returns ErrCellInvalidConfig when nil. The closed contract established by codegen + runtime/auth.Route.BootstrapAuth requires this to be wired by the composition root before slice initialisation.
func WithCASProtocol ¶
WithCASProtocol injects the CAS Protocol used by the ChangePassword path (S6 CHANGEPASSWORD-CONCURRENT-SEMANTICS-01). The Protocol declares which DB column carries the monotonic version counter and which conflict policy to apply on mismatch.
REQUIRED: initValidate() rejects nil with ErrCellInvalidConfig so that the cell will not start without a properly-configured CAS primitive. Composition root constructs the Protocol via cas.MustNewProtocol and passes it here; cells must not construct it directly (CAS-PROTOCOL-COMPOSITION-ROOT-01 archtest enforces this).
Both bare-nil and typed-nil *cas.Protocol are rejected at phase0.
func WithClock ¶
WithClock sets the time source for this Cell. Required — Init() panics via clock.MustHaveClock if not set. Composition root passes clock.Real(); tests inject a deterministic clock to control time-sensitive logic.
func WithConfigEventCollector ¶
func WithConfigEventCollector(collector obmetrics.ConfigEventCollector) Option
WithConfigEventCollector injects config-event consumer process metrics.
func WithConfigGetter ¶
func WithConfigGetter(c ports.ConfigGetter) Option
WithConfigGetter injects the ConfigGetter used by the configreceive slice to fetch the current config entry value from configcore after an upsert event (contract: http.config.internal.get.v1). When not set the slice operates in log-only mode — no cross-cell HTTP call is made.
Tests and composition roots inject an implementation directly. Concrete factories live in cell-owned adapter subpackages so the root Cell API stays port-oriented.
func WithCursorCodec ¶
func WithCursorCodec(codec *query.CursorCodec) Option
WithCursorCodec sets the cursor codec for pagination. Required in durable mode.
func WithEmitter ¶
WithEmitter injects a pre-composed outbox.Emitter directly into the Cell. Preferred path for tests and for composition roots that have already built an Emitter (e.g. outbox.NewNoopEmitter(), a custom wrapper, or a fake that records outbox entries for assertions).
Mutually exclusive with WithOutboxDeps — setting both causes Init() to fail fast with ErrCellInvalidConfig. Durability for L2 slice upgrades is derived from outbox.ReportDurable(emitter); Emitter implementations that do not expose DurabilityReporter are treated as non-durable.
ref: kubernetes/client-go rest.RESTClientFor — factory composes the typed client; resulting struct does not retain raw config fields.
func WithInMemoryDefaults ¶
func WithInMemoryDefaults() Option
WithInMemoryDefaults configures in-memory repositories for development and testing. Not suitable for production use. sessionRepo and refreshStore construction are deferred to Init() so that c.clk is available.
func WithJWTIssuer ¶
WithJWTIssuer sets the RS256 JWT issuer for token signing.
func WithJWTVerifier ¶
func WithJWTVerifier(verifier *auth.JWTVerifier) Option
WithJWTVerifier sets the RS256 JWT verifier for token validation.
func WithMetricsProvider ¶
WithMetricsProvider sets the metrics provider used by the DirectEmitter and refresh-token GC worker.
func WithOutboxDeps ¶
func WithOutboxDeps(pub outbox.CellPublisher, writer outbox.CellWriter) Option
WithOutboxDeps 注入 sealed CellPublisher 和 CellWriter,由 composition root 通过 outbox.WrapPublisherForCell / outbox.WrapWriterForCell 包装得到。 框架在 Init() 时通过 cell.ResolveEmitter 将二者组合为 outbox.Emitter, 并应用 cell 的 durability-mode 策略。
详见 ADR 202605101900-adr-cell-raw-infra-sealed-marker §D1。
Accumulative: a nil argument leaves the previously-set value in place, so `WithOutboxDeps(pub, nil)` and `WithOutboxDeps(nil, writer)` may be called separately to wire publisher and writer independently. The pairing rules in ResolveEmitter still apply (demo mode allows publisher-only; durable mode requires real writer + txRunner).
Does NOT clear previously-set deps: `WithOutboxDeps(nil, nil)` is a no-op, not a reset. To switch between direct-injection (WithEmitter) and composed (WithOutboxDeps) paths, construct a fresh Cell instead of trying to toggle.
Mutually exclusive with WithEmitter — Init() fails fast if both are set.
func WithRefreshGC ¶
WithRefreshGC enables the refresh-token GC lifecycle worker.
func WithRefreshStore ¶
WithRefreshStore injects the refresh.Store used for opaque refresh token Issue/Rotate/Revoke. Required in production (durable) mode — demo mode falls back to an in-memory store via WithInMemoryDefaults.
func WithRoleRepository ¶
func WithRoleRepository(r ports.RoleRepository) Option
WithRoleRepository sets the RoleRepository.
func WithSessionRepository ¶
func WithSessionRepository(r ports.SessionRepository) Option
WithSessionRepository sets the SessionRepository.
func WithSetupLock ¶
WithSetupLock injects a cross-process advisory lock for the admin-provisioning path (multi-pod PG deployments). When set, CreateAdmin acquires the lock at the start of the RunInTx body before calling adminprovision.Ensure — the lock, user write, and outbox emit share one transaction. Nil is a no-op (mem mode keeps the intra-process sync.Mutex). Closes backlog ADMINPROVISION-DIST-LOCK-01.
func WithTxManager ¶
func WithTxManager(tx persistence.CellTxManager) Option
WithTxManager sets the CellTxManager for transactional guarantees (L2 atomicity). Composition roots construct via persistence.WrapForCell.
func WithUserRepository ¶
func WithUserRepository(r ports.UserRepository) Option
WithUserRepository sets the UserRepository.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package configgetter wires accesscore ConfigGetter adapters.
|
Package configgetter wires accesscore ConfigGetter adapters. |
|
internal
|
|
|
adapters/http
Package http provides HTTP adapter implementations for accesscore's outbound cross-cell calls.
|
Package http provides HTTP adapter implementations for accesscore's outbound cross-cell calls. |
|
adapters/postgres
Package postgres provides cell-private PostgreSQL implementations of the accesscore port interfaces.
|
Package postgres provides cell-private PostgreSQL implementations of the accesscore port interfaces. |
|
adminprovision
Package adminprovision encapsulates the idempotent, race-safe "bring the first admin into existence" domain logic shared by two consumers:
|
Package adminprovision encapsulates the idempotent, race-safe "bring the first admin into existence" domain logic shared by two consumers: |
|
domain
Package domain contains the accesscore Cell domain models.
|
Package domain contains the accesscore Cell domain models. |
|
dto
Package dto contains accesscore's local typed views of cross-cell event payloads.
|
Package dto contains accesscore's local typed views of cross-cell event payloads. |
|
mem
Package mem provides in-memory repository implementations for accesscore.
|
Package mem provides in-memory repository implementations for accesscore. |
|
ports
Package ports defines accesscore's outbound dependency interfaces.
|
Package ports defines accesscore's outbound dependency interfaces. |
|
sessionmint
Package sessionmint centralizes access-JWT issuance so that login, IssueForUser (change-password flow), and refresh share a single fail-closed "fetch roles → sign access" pipeline.
|
Package sessionmint centralizes access-JWT issuance so that login, IssueForUser (change-password flow), and refresh share a single fail-closed "fetch roles → sign access" pipeline. |
|
testutil
Package testutil provides shared test fixtures for cells/accesscore tests.
|
Package testutil provides shared test fixtures for cells/accesscore tests. |
|
Package postgres exposes accesscore-owned PostgreSQL repository factories to composition roots while keeping the concrete implementations inside the cell's internal adapter tree.
|
Package postgres exposes accesscore-owned PostgreSQL repository factories to composition roots while keeping the concrete implementations inside the cell's internal adapter tree. |
|
slices
|
|
|
authorizationdecide
Package authorizationdecide implements the authorization-decide slice: RBAC-based authorization decisions.
|
Package authorizationdecide implements the authorization-decide slice: RBAC-based authorization decisions. |
|
configreceive
Package configreceive implements the config-receive slice: consumes config state-sync events from configcore.
|
Package configreceive implements the config-receive slice: consumes config state-sync events from configcore. |
|
identitymanage
Package identitymanage implements the identity-manage slice: CRUD + Lock/Unlock user accounts.
|
Package identitymanage implements the identity-manage slice: CRUD + Lock/Unlock user accounts. |
|
rbaccheck
Package rbaccheck implements the rbac-check slice: HasRole / ListRoles queries for a given user.
|
Package rbaccheck implements the rbac-check slice: HasRole / ListRoles queries for a given user. |
|
sessionlogin
Package sessionlogin implements the session-login slice: password-based login with JWT access token and opaque refresh token issuance.
|
Package sessionlogin implements the session-login slice: password-based login with JWT access token and opaque refresh token issuance. |
|
sessionlogout
Package sessionlogout implements the session-logout slice: revokes sessions and publishes revocation events.
|
Package sessionlogout implements the session-logout slice: revokes sessions and publishes revocation events. |
|
sessionrefresh
Package sessionrefresh implements the session-refresh slice: validates an opaque refresh token via refresh.Store and issues a fresh access JWT.
|
Package sessionrefresh implements the session-refresh slice: validates an opaque refresh token via refresh.Store and issues a fresh access JWT. |
|
sessionvalidate
Package sessionvalidate implements the session-validate slice: verifies access tokens and returns Claims.
|
Package sessionvalidate implements the session-validate slice: verifies access tokens and returns Claims. |
|
setup
Package setup implements the interactive first-run admin provisioning slice.
|
Package setup implements the interactive first-run admin provisioning slice. |