API keys and audit trails

Issue scoped machine credentials, authenticate them at the server boundary, and record security-relevant actions without turning logs into policy.

Supported approaches

API key lifecycle

available

Issue once-visible secrets, store only verifiers, rotate credentials, and revoke keys without changing application identity.

Packages

@playstack/api-keys

Frameworks and integrations

Scoped machine authentication

available

Resolve key subjects and scopes into NestJS request context before account and entitlement enforcement.

Frameworks and integrations

Structured audit recording

available

Persist actor, action, target, scope, and request context for security and support workflows.

Frameworks and integrations

Frameworks and integrations

framework

NestJS

Connect portable Playstack capabilities to dependency injection, guards, decorators, request context, workers, and lifecycle hooks.

integration

Prisma

Persist Playstack capabilities through explicit application-owned Prisma clients, transactions, and managed schema fragments.

Package reference

@playstack/api-keys

Human sessions and machine credentials share policy, not secrets

API keys identify integrations, automation, and service clients. They do not masquerade as user sessions. Once authenticated, both can enter the same account, entitlement, rate-limit, and audit boundaries through a normalized request subject.

Issue once, verify repeatedly

ts
import { createApiKeys } from '@playstack/api-keys'

const apiKeys = createApiKeys({ persistence, crypto, clock, ids, events })

const issued = await apiKeys.issue({
  subject: { type: 'account', id: account.id },
  name: 'Deployment automation',
  scopes: ['releases:read', 'releases:write'],
})

// `issued.secret` is shown once; persistence receives only its verifier.

The Nest binding authenticates the key, resolves its canonical subject and scopes, and places that result into request context. Application handlers still enforce the capability they require.

Audit facts, not diagnostic prose

ts
await audit.record({
  actor: request.actor,
  action: 'release.published',
  target: { type: 'release', id: release.id },
  accountId: request.account.id,
  context: request.operation,
})

Audit records are durable product facts with explicit retention and access policy. Operational logs remain a separate stream and should not become the only account of who changed access. Actor types include users, API keys, staff, and system activity while remaining extensible for application principals such as partners or services.

Go

Playstack Pro tag
OriginsPricingBlogNewsletterChangelogStatusRoadmap
ContributorsCommunityIn Use ShowcaseCase StudiesPartnersSponsors
FAQsSupportContact

© 2026 Playstack. All rights reserved.

With OSS
Terms of ServicePrivacy PolicyCookie PolicyImprint

By

Commune Software