CORS, Rate Limiting, Audit
The platform stacks several controls on top of authentication and RBAC. Each is implemented in packages/api/internal/middleware/* and is composable — the production server enables all of them.
13.7.1 CORS
CORS is configured in the router using Chi’s cors middleware. The default production configuration:
VERIFY: confirm the exact CORS config block in
router.go. Dev origins:http://localhost:5173(Portal Vite) andhttp://localhost:8081(Expo dev). Add only what you need; never use*withAllowCredentials: true(browsers will reject it).
13.7.2 Rate limiting
Verified in packages/api/internal/middleware/ratelimit.go. Implements a token bucket per client:
Client identity (priority order, see identifyClient in ratelimit.go:159-181):
X-API-Keyheader (most specific — gives the partner their own bucket)Authorizationheader (first 20 chars used as key)X-Forwarded-ForIPX-Real-IPRemoteAddr
Response headers (always set, even on success):
On limit exceeded (429 Too Many Requests):
Per-key limits (programmatic at startup):
Recommended production settings:
- Public endpoints (
/credentials/verify,/dids/resolve): 50 req/s burst 100 per IP.- Authenticated user endpoints: 100 req/s burst 200 per JWT.
- Admin / API-key callers: 500 req/s burst 1000 per key.
13.7.3 Audit logging
The platform ships with two layers of logging (verified in middleware/logging.go):
Layer 1 — Request log (Zap, structured JSON):
Every line includes a request_id (UUIDv7 / ULID) propagated via X-Request-Id so a client log can be tied to a server log without grepping.
Layer 2 — Audit events (table audit_events, append-only):
Recommended audit-worthy actions (issuer/verifier-side):
VERIFY: confirm whether
audit_eventsis the canonical table or whether logging is solely via Zap. If only Zap, recommend adding the table for compliance retention. Retention: 90 days hot in Postgres, then archive to S3 / object storage. Compliance environments (EU AI Act, ISO 27001) typically require 12–24 months.
13.7.4 Security headers
The Portal nginx config (packages/portal/nginx.conf) and the API edge are responsible for:
CSP note: the Portal’s React build inlines a small CSS critical block —
'unsafe-inline'for styles is the minimum compromise; remove it once styled-components ornonceis wired up.
13.7.5 TLS & certificate hygiene
- TLS 1.2 minimum at the edge (1.3 preferred). Disable RC4, 3DES, SHA-1.
- Wildcard cert:
*.adid.devcovers Portal, API, Wallet OTA channel. Renew via cert-manager + Let’s Encrypt (HTTP-01 or DNS-01). - HSTS preload: submit
adid.devto the HSTS preload list once you are confident TLS is permanent. - mTLS for partner integrations: if you accept high-volume partner traffic, terminate mTLS at the LB and forward
X-Client-Cert-Subjectto the API.