@useoneauth/credentials
v1.0.0
Published
> Phase 2 — Credential Engine. Lifecycle-managed, versioned, rotatable secrets bound to an identity.
Readme
@useoneauth/credentials
Phase 2 — Credential Engine. Lifecycle-managed, versioned, rotatable secrets bound to an identity.
Pure TypeScript, no database or transport. Services hold business logic and emit
immutable events; persistence is expressed through repository interfaces with
in-memory adapters. Secrets are hashed via a Hasher port (scrypt) and never
stored or returned in raw form (except a one-time API-key disclosure at issue).
Concrete credential types this phase: Password and API Key. More types
(Passkey, OAuth, Magic Link, …) slot in later behind the same
CredentialTypeStrategy interface.
Install
// package.json
{ "dependencies": { "@useoneauth/credentials": "workspace:*" } }Usage
import {
CredentialService, RotationService,
InMemoryCredentialRepository, InMemoryCredentialVersionRepository, InMemoryCredentialPolicyRepository,
PasswordStrategy, ApiKeyStrategy, ScryptHasher,
} from "@useoneauth/credentials"
import { InMemoryEventBus } from "@useoneauth/events-core"
const strategies = new Map([
["password", new PasswordStrategy()],
["api_key", new ApiKeyStrategy()],
])
const creds = new CredentialService(
new InMemoryCredentialRepository(),
new InMemoryCredentialVersionRepository(),
new InMemoryCredentialPolicyRepository(),
strategies,
new ScryptHasher(),
new InMemoryEventBus(),
)
// Issue an API key — the raw value is disclosed exactly once.
const { credential, disclosedSecret } = await creds.issueCredential({ identityId: "u1", type: "api_key" })
// Verify a presented secret.
await creds.verifyCredential(credential.id, disclosedSecret!) // => trueRotation with a grace window
const rotation = new RotationService(/* same deps as above */)
await rotation.rotateCredential({ credentialId: credential.id })
// old version → grace (still valid until expiresAt); new version → active
await rotation.sweepExpired() // retire grace versions past their expiryLifecycle
- Credential.status:
active→rotating→active; any →revoked. - CredentialVersion.status:
active→grace→retired; any →revoked.
Events
CREDENTIAL_CREATED, CREDENTIAL_ROTATED, CREDENTIAL_REVOKED (persist → publish).
Scripts
pnpm --filter @useoneauth/credentials test
pnpm --filter @useoneauth/credentials test:cov
pnpm --filter @useoneauth/credentials typecheckSee ARCHITECTURE.md for the ports/adapters, hashing, and rotation design.
