Policy as code, enforced before merge
Auth, rate limits, schema validation, and audit logging defined once and applied to every route. Enforced in CI before any change lands. Immutable account-level audit logs, RBAC for the management plane, SOC 2 Type II — built so compliance reviews aren't a tax on shipping.
@alice · touches 6 routes
Governance by Slack message doesn't survive the next audit
When policy lives in conventions instead of code, every team interprets it differently. The auditor finds the gap. The compliance review extends the launch. The CISO loses sleep.
Each team enforces its own definition of "production-ready"
Three teams, three rate-limit conventions, three logging formats. Auditors ask "how do you ensure all APIs require auth?" and the honest answer is "we Slack each team and hope."
Compliance reviews block ship velocity
A new endpoint takes two engineering days to implement and two weeks to clear "the security review." The slowdown is the cost of not having policy enforced automatically.
Audit logs scattered across five places
Authentication logs in Auth0, gateway logs in CloudWatch, app logs in Datadog, deploy logs in GitHub, account changes in your IDP. Compiling a single audit trail for one customer takes a sprint.
"Who changed the prod rate limit at 2am?"
A control-plane click changed something critical. There's no PR, no diff, no immutable audit. Engineering manager spends Monday morning piecing together the timeline from Slack DMs.
Define it once. Enforce it in CI. Audit it forever.
One policy, every route
Define rate limits, auth, schema validation, and audit logging once as a shared policy or composite. Reference it from every route. Update it once — every route inherits.
Enforced in your PR, not after deploy
Config is files in Git. CI runs your governance checks before merge — auth required on every route, no inline rate limits, schema validation on body-bearing requests. Violations block the merge.
SOC 2 audit, not Slack archaeology
Every config change is a Git commit. Every account action is in the immutable audit log with full actor and resource context. Every gateway request is logged with caller identity and exported to your SIEM. One place per dimension, all queryable.
One bundle. Every route. Reviewed in a PR.
Wrap your "production-ready" requirements into a single named Composite Inbound policy. Apply it to every public route. Run a governance check in CI to fail any PR that ships a route without it.
Compliance you can show, not pay a consultant to assemble
OpenAPI is the source of truth
Routes live in `config/routes.oas.json` — a standard OpenAPI document with `x-zuplo-*` extensions for handlers and policies. Lint with Spectral in CI, generate clients with Speakeasy or RateMyOpenAPI, write tests against the schema. The gateway and the docs and the SDKs all read the same file.
Composite policies as governance bundles
Bundle "production-ready" into a Composite Inbound policy: api-key-auth → rate-limit-prod → request-validation → audit-log-export. Apply the composite to every public route. New routes inherit the full policy stack with one line — no opportunity to forget a step.
Account-level immutable audit
Every project mutation, deployment, team change, API key operation — captured with full actor (sub, email, IP, geo, ASN), resource (type/ID), and outcome. 90-day default retention, query via Developer API, export to your SIEM. Pre-baked for SOC 2 evidence collection.
Data residency on your terms
Managed Edge for global low latency. Managed Dedicated single-tenant on the cloud and region of your choice (EU-only, US-only, regulated cloud) when sovereignty requires it. Self-Hosted on your Kubernetes when nothing leaves your perimeter. Same policies, every surface.
What teams use this for
“Auditor needs proof every API requires authentication.”
Show them `config/policies.json` (one shared `api-key-auth-inbound` policy), the Composite Inbound bundle that includes it, and your CI script that fails if any route doesn't reference the composite. Three files, one queryable Git history, one minute.
“We need to roll out a new rate limit across 47 routes.”
Update the shared `rate-limit-prod` policy in one place. Every route that references it inherits the new value. Open a PR. Reviewers see one diff, one test run, one merge — instead of 47 individual changes.
“Customer wants 12 months of audit logs for a SOC 2 review.”
Export the account audit log via the Developer API to your S3-backed log archive. Combined with gateway logs in your SIEM (Datadog, Splunk, etc.), you have an immutable trail covering both control-plane changes and data-plane traffic — exactly what the auditor wants.
“Force partners off a deprecated API version on a known schedule.”
Attach the Brownout policy to the deprecated routes. It returns scheduled 503s during specified windows — first an hour a week, then a day, then full sunset — so partners feel the deprecation as concrete downtime instead of an email they ignored. The policy lives in your repo with a date-driven config; no last-minute pull-the-plug ops.
Frequently Asked Questions
Common questions about API governance and compliance on Zuplo.
Compliance shouldn't slow shipping
Free Zuplo project, define one shared policy, apply it to every route — and watch your CI block the next governance regression before it merges.