Skip to main content

runtime-state

Maintain host-independent persistent runtime state, its reusable directory parser, encrypted records and generated keys, portal and portal-free OAuth sessions, refresh/OIDC replay history, local identity epochs, restart E2E tests, and embedding lifecycle contracts.

소스 정보

저장소
greenpau/go-authcrunch
최근 소스 활동
2026년 10월 10일 16:01
감지된 SKILL.md 언어
영어
스타
60
포크
66

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
3 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
runtime-state
description
Maintain host-independent persistent runtime state, its reusable directory parser, encrypted records and generated keys, portal and portal-free OAuth sessions, refresh/OIDC replay history, local identity epochs, restart E2E tests, and embedding lifecycle contracts.
# Runtime State ## Configuration and ownership `authcrunch.Config.State` (`state`) opts the root runtime into persistence with `*state.Config`. Omission keeps the previous volatile behavior. A present empty configuration is invalid. The only setting is `Directory` (`directory`), an absolute non-root path. Validation normalizes it without filesystem writes. `pkg/state/parser.NewStateConfigFromDirectives(statements)` parses exactly one encoded `directory PATH` body statement. Hosts own traversal, placeholders and `cfgutil.EncodeArgs`; the public parser owns grammar and typed validation. Empty blocks, duplicates, unknown settings and extra arguments fail. Apply the result to `Config.State` before `NewServer`. There are no Docker, Caddy, HTTP, environment-variable or global-directory dependencies. Read [configuration and operations](references/configuration-and-operations.md) for retained state, restart guarantees, backups and deployment limits. Hosts adapt their configuration syntax to the public parser and coordinate runtime ownership. Do not change or run tooling in sibling repositories. ## Storage invariants `pkg/state/{store,catalog,codec}.go` owns `Store` and `Record`. `state.Open` creates private 0700 local storage, holds an exclusive advisory `owner.lock`, and reuses a private 0600 AES-256 key in `master.key`. Record filenames are SHA-256 hashes of trusted component names. AES-GCM authenticates the envelope version, binding and payload with the filename as associated data. A separately authenticated catalog detects missing committed records. Reject corruption, missing key/catalog, unsafe permissions, symlinks, and concurrent owners. Use local Unix filesystems with reliable locks, atomic replacement and directory sync. Windows persistence fails closed: secure ACL and durable directory support are not implemented. Do not weaken commits to make an unsupported platform pass. When creating a state directory hierarchy, sync the containing directories too; syncing records alone does not persist newly created directory entries. Save a complete private snapshot under the component mutex. Commit an intent marker, synced temporary record, atomic rename and directory sync; remove/sync the marker before acknowledging success. An interrupted marked record is retired on reopen, sacrificing its sessions rather than resurrecting a possible revocation. Failed disk commits poison the store. No failed write may publish a credential, redirect, successful logout or subsequent state-backed cached authentication. Successful mutations are durable before Close; Close only releases resources. Never accept persistence DTOs from HTTP. `Record.Encode/Decode` uses gob to retain server-only proof fields whose public JSON/XML/YAML tags remain `-`. The encrypted envelope is format version 1; evolving DTO/security semantics requires a reviewed migration or explicit invalidation. Bounded snapshots reject oversized records. Keep plaintext snapshots, keys and credentials out of errors and logs. Transactional consumers can call `Record.PrepareEncode` before committing a candidate and then `Save` the prepared bytes. `state.ErrCapacity` from preparation leaves the record and store unchanged: reject or undo the candidate without discarding existing authority. Ordinary `Encode`/`Save` retain fail-closed behavior for oversized mutations. This is an encoded-payload limit, not a hard bound on gob's internal staging allocation; retain component input and count limits. Count and request-size limits do not bound the aggregate snapshot. All session admissions and rotations must prepare their candidate and undo it on capacity refusal. Preserve previous sessions, replacement targets, and complete replay history. A full component must not disable unrelated persistent consumers. Deletion and terminal revocation must remain possible at the record limit. ## Runtime integration `server_persistent_state.go` binds sessions to a random configuration epoch stored under the digest of the normalized security configuration, excluding the storage path and diagnostic-only `Logging` settings. Logging rule additions, changes, and removal must preserve valid persisted sessions; `server_logging_e2e_test.go` exercises that invariant through real TLS restarts. Every other observed configuration transition within that directory changes the epoch, including removal of a component; returning to an older configuration cannot restore that component's old authority. Reordering or unrelated configuration changes can conservatively require login. Stable generated KMS keys use separate bindings and survive these session invalidations. Root construction opens storage first and owns it last during reverse cleanup. It injects KMS storage before constructing keys, restores local identity epochs, then attaches session state before publication. `Server.Close` leaves durable records intact. Each directory has one live owner: drain and close the old runtime before opening its replacement. Opening new-before-closing-old must fail, not fall back to memory. This is not a distributed store or overlapping reload API. | Owner | Persistent integration | | --- | --- | | `pkg/kms` | `CryptoKeyStoreConfig.SetStateStore`; generated ES512/EdDSA/Ed25519 material is bound to generation tag and algorithm family; no process-global key sharing in persistent mode | | `pkg/user` | `MarshalSession` / `UnmarshalSession` retain canonical identity and private login proof, rebuild derived maps, and exclude unfinished authenticator secrets | | `pkg/authn/cache` | `SessionCache.ConfigurePersistentState` restores only unexpired completed users; Add/Delete commit synchronously | | `pkg/authn/token_refresh` | `MemoryStore.ConfigurePersistentState` retains complete families, original authentication time/deadlines, current digest and every spent digest | | `pkg/authz` | `Gatekeeper.ConfigurePersistentState` restores completed direct OAuth sessions; origin binding and current ACL evaluation remain mandatory | | `pkg/identity`, `pkg/ids/local` | `ConfigurePersistentState` retains the backend epoch only for the exact recorded identity-file digest; transactions update that digest under the existing file lock | | `pkg/oidc` | `Provider.ConfigurePersistentState` retains browser sessions, consent, codes and complete access/refresh families; issuance commits inside the current-identity transaction | | `pkg/authn` | `Portal.ConfigurePersistentState` attaches its owned components and rejects HTTP/BasicAuth after storage failure | Standalone consumers own the `state.Store`, choose trusted names and bindings, configure components before exposing them, and close storage after draining all consumers. A custom binding must cover issuer, providers, policies, clients, identity and signing configuration. Directly configured standalone components must also invalidate removed/reintroduced namespaces; root `NewServer` supplies that configuration-epoch behavior automatically. Preserve spent credentials until no descendant remains live. Restoring only current refresh hashes or clearing replay history at restart is a security bug. Validate restored sessions and grants in detached maps, then publish them together. A failed restore must leave no partially restored authority, including through standalone OAuth gatekeeper and OIDC provider APIs. Refresh gob snapshots retain typed provider source, provider trust digest and bounded captured claim bytes as well as complete replay history. Restore rejects unknown sources, mixed local/provider evidence, invalid JSON, unsupported kinds and oversized snapshots before publishing detached state. Current provider trust and canonical claim checks still run at renewal. Keep provider configuration in custom portal bindings; persistence does not turn captured claims into live upstream revalidation. Provider cached users retain no local credential proof. `TestPersistentProviderEvidenceRejection` and the provider portal TLS restart journey cover these boundaries alongside existing local identity epochs. The portal response guard strips staged headers/cookies when a later composite login commit fails; preserve this even when the earlier session write succeeded. Check component health as well as the backing store: a session serialization failure can poison the cache without a failed disk write. Both HTTP and BasicAuth must reject that portal state. OIDC HTTP responses are buffered: a failed commit must discard success headers, body, redirects and cookies. Hosts composing OIDC logout/login must use `LogoutWithError` / `ClearSessionWithError` and stop on error. Existing void methods emit an unavailable response for compatibility. Recoverable OIDC capacity errors also require composite login cleanup: remove new portal sessions, revoke undelivered refresh families with a bounded context independent of request cancellation, and restore pre-credential response headers. Do not undo earlier completed revocations. Consult the OIDC skill for candidate rollback and revocation-size invariants. Local identity files remain the source of current account status and credential versions. Persist their epoch after an atomic identity write and before granting authority from current identity. Keep persistence attached to transaction targets, including self-service mutations; `Database.Copy` must not modify the source's state record. File mismatch chooses a fresh epoch, never trusts serialized `loaded_at` as authentication evidence. During attachment, adopt the identity snapshot read under the file lock before binding its digest to an epoch; the constructor's earlier in-memory snapshot may already be stale. Rolling back both the identity file and its entire matching state backup requires external rollback protection. ## Validation Keep parser tests external with an executable constructor example. Use the parser in root TLS consumers and the actual `authdb` executable fixture. - `pkg/state/*_test.go`: configuration, private authenticated storage, locking, corruption/missing files, independent snapshots, interrupted writes, process exit without Close, nested directory creation, partial first initialization, and failure poisoning. - `pkg/kms/persistent_state_test.go`: all generated algorithms, old JWT verification after reopen, and independent-directory key isolation. - `pkg/user/session_state_test.go`, `pkg/authn/cache/session_state_test.go`: private-proof fidelity, derived authorization fields, expiry/deletion/failure. - `pkg/authn/token_refresh/persistent_test.go`, `pkg/oidc/persistent_state_test.go`: rotation, complete spent history, replay revocation, expiry, commit failure, and capacity refusal that preserves existing credentials and unrelated records. - `pkg/authn/oidc_completion_e2e_test.go`: real browser login rejects recoverable OIDC capacity refusal without delivering credentials or leaking session slots; healthy retry succeeds at the configured refresh capacity. - `pkg/authz/oauth_test.go`, `pkg/oidc/persistent_state_test.go`: atomic restoration rejection through unit and real TLS consumers. - `pkg/identity/persistent_state_test.go`: unchanged-file continuity, durable security-version revocation, self-service transactions, identity-file rollback, and file replacement between database construction and persistence attachment. - `server_persistent_state_e2e_test.go`: TLS portal-free OAuth, lost pending login, ACL checks, logout, config serialization and removal/reintroduction; portal session/profile, native refresh, OIDC consent/code/access/refresh and replay; interrupted commit recovery, failed final login commits, and failed construction releasing exclusive ownership. - `cmd/authdb/persistent_state_e2e_test.go`: built executable, real browser login, SIGKILL, same-address restart, identical JWKS and surviving old credentials. ```sh make test TEST_DIR='./pkg/state/... ./pkg/user ./pkg/kms ./pkg/authn ./pkg/authn/cache ./pkg/authn/token_refresh ./pkg/authz ./pkg/identity ./pkg/oidc . ./cmd/authdb ./internal/tag' TEST='State|Store|RecordCodec|ConfigValidation|Persistent|SessionState|Capacity|TagCompliance|TestE2EAuthdb' COVERAGE_DIR='.coverage/runtime-state' make ci-check ``` The [testing contract](../testing-and-ci/SKILL.md) defines diagnostics and artifact interpretation. The default full suite must retain volatile-mode replacement tests alongside persistent-mode journeys; opt-in storage must not change existing omission semantics.
GitHub에서 보기