Add governance to my CI/CD
You live in your terminal and your CI/CD pipeline. You want API governance without opening a dashboard.
What you need
Section titled “What you need”- An Apiway tenant (register free — no card, and free credit to explore with; every capability is on every tier, so see pricing only for how much usage each one carries)
- A CI/CD pipeline (GitHub Actions, GitLab CI, Azure Pipelines, Jenkins — anything that can make HTTP calls)
- Your OpenAPI specs in your repository
The pipeline
Section titled “The pipeline”-
Add a governance check to your pipeline
On every pull request that changes an OpenAPI spec, call the platform API:
# GitHub Actions example- name: Check API governancerun: |curl -X POST https://core.api.apiway.net/v1/programmes/validate \-H "Authorization: Bearer ${{ secrets.APIWAY_TOKEN }}" \-H "Content-Type: application/json" \-d '{"specification": "'$(base64 -w0 openapi.yaml)'"}'The platform returns:
- Compliance score against your design standards
- Breaking change detection against the previous version
- Security analysis (missing auth, open endpoints)
- Recommendations for improvement
-
Fail the build on violations
Set your quality gate:
- name: Enforce governancerun: |SCORE=$(curl -s https://core.api.apiway.net/v1/programmes/{id}/compliance \-H "Authorization: Bearer ${{ secrets.APIWAY_TOKEN }}" \| jq '.score')if [ "$SCORE" -lt 80 ]; thenecho "API compliance score $SCORE is below threshold (80)"exit 1fiBreaking changes? Build fails. Missing security? Build fails. Non-compliant naming? Build fails. All before a human reviewer even looks at it.
This step checks the design. Your implementation is verified against the contract on every push by default — including code changes that do not touch the contract — with nothing to add to your pipeline.
-
Auto-deploy on merge
When the PR merges, deploy through the full pipeline:
- name: Deploy APIif: github.ref == 'refs/heads/main'run: |curl -X POST https://core.api.apiway.net/v1/programmes \-H "Authorization: Bearer ${{ secrets.APIWAY_TOKEN }}" \-H "Content-Type: application/json" \-d '{"name": "Orders API","specification": "'$(base64 -w0 openapi.yaml)'"}'Governance, security, deployment, activation — all automated. The 8-step pipeline runs without a single click.
-
Use MCP for local development
Before you even push, your AI coding assistant can check governance:
“Check if my Orders API spec passes governance”
“Deploy my updated Payments API to staging”
“Show me which consumers are subscribed to the Orders API”
The assistant calls the same platform API. Same governance. Same rules. Different interface.
Example: full pipeline
Section titled “Example: full pipeline”name: API Governanceon: pull_request: paths: ['**/openapi.yaml', '**/openapi.json'] push: branches: [main] paths: ['**/openapi.yaml', '**/openapi.json']
jobs: governance: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Validate & score id: validate run: | RESULT=$(curl -s -X POST https://core.api.apiway.net/v1/programmes/validate \ -H "Authorization: Bearer ${{ secrets.APIWAY_TOKEN }}" \ -H "Content-Type: application/json" \ -d '{"specification": "'$(base64 -w0 openapi.yaml)'"}')
echo "score=$(echo $RESULT | jq '.score')" >> $GITHUB_OUTPUT echo "$RESULT" | jq '.findings[]'
- name: Enforce quality gate if: github.event_name == 'pull_request' run: | if [ "${{ steps.validate.outputs.score }}" -lt 80 ]; then echo "::error::API governance score ${{ steps.validate.outputs.score }}/100 — below threshold" exit 1 fi
- name: Deploy if: github.ref == 'refs/heads/main' run: | curl -X POST https://core.api.apiway.net/v1/programmes \ -H "Authorization: Bearer ${{ secrets.APIWAY_TOKEN }}" \ -H "Content-Type: application/json" \ -d '{ "name": "Orders API", "specification": "'$(base64 -w0 openapi.yaml)'" }'What you got
Section titled “What you got”- Automated quality gate — every spec change checked before merge
- Breaking change detection — caught in the PR, not in production
- Zero UI dependency — everything via API calls in your pipeline
- Same governance — CI/CD, CLI, MCP, and UI all enforce the same rules
- Audit trail — every check, every deploy, every approval recorded
GitOps without rebuilding the house
Section titled “GitOps without rebuilding the house”If your team runs its infrastructure through GitOps, your first instinct may be to put Apiway in your repository too: the gateway, the authorisation server, every client and scope, declared in Terraform and applied by your pipeline. It is a sound instinct for infrastructure you own. For a platform you bought, it is like saying “I really like your house — now give me the blueprints so I can rebuild it.” The point of the house is that you do not have to build it.
What changes, and who changes it
Section titled “What changes, and who changes it”GitOps assumes one team authors all of the desired state and nothing else changes it. Apiway’s state is produced by many parties, all the time:
- a customer subscribes at two in the morning, and their credentials and scopes exist;
- an approver signs off, and a version goes live;
- a credential rotates on its own schedule;
- protection acts on a caller that is misbehaving;
- a new design arrives, and customers start calling its mock.
None of that can wait for a pull request, and most of it is not yours to author — a customer’s sign-up belongs to the customer. A repository mirroring it would always be behind, or a pipeline would be chasing every event. You would not keep your customers’ sign-ups in Git; you keep the contract that decided what they could sign up for.
What belongs in your repository
Section titled “What belongs in your repository”What your team authors: the contract. Your OpenAPI specification — and your service levels — live in your repository, change through pull requests, and are checked on every push, exactly as the pipeline above shows. That is your one declaration.
Everything else follows from it. Routes, security, per-operation scopes, limits and quotas are derived from the contract rather than configured next to it, so there is no second description to keep in step, and nothing of that kind to drift.
Nothing to configure in the authorisation server
Section titled “Nothing to configure in the authorisation server”The authorisation server is not something you configure. It behaves as the OAuth 2.0 and OpenID Connect standards say — discovery, signing keys, revocation, PKCE — the same for every customer. Clients, scopes and grants are not settings: they follow from subscriptions and the contract.
That is deliberate. Every setting on an authorisation server is a way to make it less standard and less safe — a longer token lifetime, a weaker way for clients to authenticate, a grant switched on “for now”. Most authorisation-server incidents are misconfigurations. Not having the settings is the security property.
Nothing secret in your pipeline (rolling out)
Section titled “Nothing secret in your pipeline (rolling out)”Declaring clients and credentials in Terraform brings their secrets back into Terraform state, readable by anyone with the state file, and applying it needs a standing administrator credential stored in your pipeline variables — the kind of secret that leaks most often. With Apiway your pipeline sends a contract and reads results through the API, and it authenticates without a stored secret: the CI system vouches for the pipeline run, and Apiway decides what it may do. (Rolling out: until then, the pipeline credential is an Apiway-issued secret you can rotate and revoke.)
What you keep from GitOps
Section titled “What you keep from GitOps”| What GitOps gave you | With Apiway |
|---|---|
| Every change reviewed | The contract changes through pull requests; the gate checks it on push |
| History and rollback | Every contract version is kept; roll back to a version; a breaking change cannot go onto a version in use |
| The same result in every environment | One contract, promoted through environments; everything else derived the same way each time |
| Knowing when something changed by hand | What runs is checked against the contract |
| Not locked into a console | Everything is an API your pipeline calls; the contract is a file you own |
One declaration instead of three, nothing to configure in the authorisation server, and — as federated pipeline credentials roll out — nothing secret in your pipeline.
Next steps
Section titled “Next steps”- Ship to production — understand the full 8-step pipeline
- Govern existing APIs — bring your current APIs under governance
- Secure for AI agents — agents can trigger the same pipeline