- Add PUT /v1/policy/rule endpoint for updating policy rules; expose
full policy CRUD through the web UI with a dedicated policy page
- Add certificate revoke, delete, and get-cert to CA engine and wire
REST + gRPC routes; fix missing interceptor registrations
- Update ARCHITECTURE.md to reflect v2 gRPC as the active implementation,
document ACME endpoints, correct CA permission levels, and add policy/cert
management route tables
- Add POLICY.md documenting the priority-based ACL engine design
- Add web/templates/policy.html for policy management UI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Admins can now revoke or delete certificate records from the cert detail
page in the web UI. Revoked certificates display a [REVOKED] badge and
show revocation metadata (time and actor). Deletion redirects to the
issuer page.
The REST API gains three new authenticated endpoints that mirror the
gRPC surface:
GET /v1/ca/{mount}/cert/{serial} (auth required)
POST /v1/ca/{mount}/cert/{serial}/revoke (admin only)
DELETE /v1/ca/{mount}/cert/{serial} (admin only)
The CA engine stores revocation state (revoked, revoked_at, revoked_by)
directly in the existing CertRecord barrier entry. The proto CertRecord
message is extended with the same three fields (field numbers 10–12).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The vault server holds in-memory unsealed state (KEK, engine keys) that
is lost on restart, requiring a full unseal ceremony. Previously the web
UI ran inside the vault process, so any UI change forced a restart and
re-unseal.
This change extracts the web UI into a separate metacrypt-web binary
that communicates with the vault over an authenticated gRPC connection.
The web server carries no sealed state and can be restarted freely.
- gen/metacrypt/v1/: generated Go bindings from proto/metacrypt/v1/
- internal/grpcserver/: full gRPC server implementation (System, Auth,
Engine, PKI, Policy, ACME services) with seal/auth/admin interceptors
- internal/webserver/: web server with gRPC vault client; templates
embedded via web/embed.go (no runtime web/ directory needed)
- cmd/metacrypt-web/: standalone binary entry point
- internal/config: added [web] section (listen_addr, vault_grpc, etc.)
- internal/server/routes.go: removed all web UI routes and handlers
- cmd/metacrypt/server.go: starts gRPC server alongside HTTP server
- Deploy: Dockerfile builds both binaries, docker-compose adds
metacrypt-web service, new metacrypt-web.service systemd unit,
Makefile gains proto/metacrypt-web targets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Registry.UnsealAll() that rediscovers mounted engines from the
barrier on unseal, using stored metadata at engine/_mounts/ with a
fallback discovery scan for pre-existing mounts (migration path)
- Registry.Mount() now persists mount metadata to the barrier;
Registry.Unmount() cleans it up
- Call UnsealAll() from both REST and web unseal handlers
- Change Unmount() signature to accept context.Context
- Default CA key size changed from P-384 to P-521
- Add build-time version stamp via ldflags; display in dashboard status bar
- Make metacrypt target .PHONY so make devserver always rebuilds
- Redirect /pki to /dashboard when no CA engine is mounted
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ARCHITECTURE.md with full system specification
- Add Project Structure and API Sync Rule to CLAUDE.md; ignore srv/
- Fix engine.proto MountRequest missing config field
- Add pki.proto PKIService to match unauthenticated REST PKI routes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add the first concrete engine implementation: a CA (PKI) engine that generates
a self-signed root CA at mount time, issues scoped intermediate CAs ("issuers"),
and signs leaf certificates using configurable profiles (server, client, peer).
Engine framework updates:
- Add CallerInfo struct for auth context in engine requests
- Add config parameter to Engine.Initialize for mount-time configuration
- Export Mount.Engine field; add GetEngine/GetMount on Registry
CA engine (internal/engine/ca/):
- Two-tier PKI: root CA → issuers → leaf certificates
- 10 operations: get-root, get-chain, get-issuer, create/delete/list issuers,
issue, get-cert, list-certs, renew
- Certificate profiles with user-overridable TTL, key usages, and key algorithm
- Private keys never stored in barrier; zeroized from memory on seal
- Supports ECDSA, RSA, and Ed25519 key types via goutils/certlib/certgen
Server routes:
- Wire up engine mount/request handlers (replace Phase 1 stubs)
- Add public PKI routes (/v1/pki/{mount}/ca, /ca/chain, /issuer/{name})
for unauthenticated TLS trust bootstrapping
Also includes: ARCHITECTURE.md, deploy config updates, operational tooling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>