Agent mode·Plain-text view for agents and LLMsraw md →

APIops in CI/CD — when your API platform behaves like a codebase

Manifests, idempotent applies, environment promotion, and the audit trail that makes the regulator's questions easy. The shape of platform-as-code for API gateways.

Dec 2, 2025 · 7 min read · Selin Demir, VP Product · Engineering

Tags: #apiops · #ci-cd · #platform · #devops


There is a steady, slow consolidation happening in API platforms. Configuration is moving out of the admin UI and into manifest files. Manifests live in Git. Git triggers pipelines. Pipelines apply manifests to environments. Environments run the resulting platforms.

That's not new. Terraform did it for infrastructure. Helm did it for Kubernetes. The shift in API platforms has lagged because API platforms are mostly clicked together in admin consoles. APIops is the name for the same shift, applied to the API plane.

This post walks through what APIops actually means in practice — not the marketing line, the operational reality.

The four primitives

APIops as a discipline is four primitives:

  1. Declarative manifests. Every entity in the platform — proxies, policies, routes, AI configurations, identity providers — has a stable YAML/JSON representation. The manifest is the source of truth.
  2. Idempotent apply. Applying the same manifest twice yields the same state. The platform converges toward the manifest, not toward "whatever happened last."
  3. Environment promotion. The same manifest applies cleanly to dev, stage, and prod. Environment-specific values are parameterized, not duplicated.
  4. Auditable trail. Every apply is recorded — actor, environment, entity, before/after — alongside every other audit event the platform captures.

If you have all four, you have APIops. If you have any three of them, you have a brittle workaround that calls itself APIops. The distinction matters.

The manifest, concretely

Manifests are flat YAML — readable in a PR, diffable in git diff, greppable in rg.

# payments-proxy.yaml
apiVersion: apinizer.io/v1
kind: ApiProxy
metadata:
  name: payments
  project: payments
spec:
  type: rest
  endpoints:
    - path: /v1/payments
      methods: [GET, POST]
  upstream:
    targets:
      - https://core.internal.example.com
    loadBalancer: round-robin
  policies:
    - ref: auth-oauth2
    - ref: rate-limit-payments
    - ref: pii-strip-default
    - ref: audit-default

The shape is intentionally boring. No exotic constructs. No templating that requires a tool to understand. A platform engineer reads it once and knows what it does.

References (auth-oauth2, rate-limit-payments) point at policy manifests that live in their own files. A single proxy might reference five or ten policies. Each policy is reusable across proxies.

Idempotent apply, in practice

The interesting property of apply isn't that it works the first time. It's that it works the fiftieth time.

# Apply once
$ apinizer apiops apply --env prod ./payments/*.yaml
Applied: 3 created, 0 updated, 0 deleted

# Apply again, no changes
$ apinizer apiops apply --env prod ./payments/*.yaml
Applied: 0 created, 0 updated, 0 deleted   # noop

# Apply after a small edit
$ apinizer apiops apply --env prod ./payments/*.yaml
Applied: 0 created, 1 updated, 0 deleted

The platform diffs the manifest against the current state and emits the minimum change set. The audit captures the actor and the diff.

Two implications:

  • Reruns are safe. A CI job that retries on flake doesn't double- apply. The second apply is a noop.
  • Drift is detectable. If someone changes a setting through the admin UI, the next manifest apply detects the drift and either reverts it (default) or alarms (configurable per policy).

Detecting drift matters in regulated environments. The auditor asks "is the running config the same as the manifest?" — apply runs and either answers "yes, no changes" or surfaces the difference.

Environment promotion

The same manifest applies to dev, stage, prod. Environment-specific values live in env-specific overlays.

# payments-proxy.yaml — base
spec:
  upstream:
    targets: ${PAYMENTS_UPSTREAM_TARGETS}
    timeoutMs: ${PAYMENTS_UPSTREAM_TIMEOUT}
# env/dev.yaml
PAYMENTS_UPSTREAM_TARGETS:
  - https://payments-dev.internal.example.com
PAYMENTS_UPSTREAM_TIMEOUT: 5000

# env/prod.yaml
PAYMENTS_UPSTREAM_TARGETS:
  - https://payments-prod-1.internal.example.com
  - https://payments-prod-2.internal.example.com
PAYMENTS_UPSTREAM_TIMEOUT: 2000

The promotion flow is the same three commands, with different env arguments:

$ apinizer apiops apply --env dev   ./payments/*.yaml
$ apinizer apiops apply --env stage ./payments/*.yaml
$ apinizer apiops apply --env prod  ./payments/*.yaml

Hot deployment means each apply lands without downtime. The audit captures who promoted what, when, and to which environment. That record is the regulator's answer to "show me how this proxy reached production."

A typical pipeline

The pipeline shape we see most often:

# .github/workflows/apiops.yaml
on:
  push:
    branches: [main]
    paths: ['apiops/**']

jobs:
  apply-dev:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: apinizer/setup-apiops@v1
      - run: apinizer apiops validate ./apiops/**/*.yaml
      - run: apinizer apiops plan  --env dev ./apiops/**/*.yaml
      - run: apinizer apiops apply --env dev ./apiops/**/*.yaml
        env:
          APINIZER_TOKEN: ${{ secrets.APINIZER_TOKEN_DEV }}

  apply-prod:
    runs-on: ubuntu-latest
    needs: apply-dev
    environment: prod-approval  # GitHub environment with manual review
    steps:
      - uses: actions/checkout@v4
      - uses: apinizer/setup-apiops@v1
      - run: apinizer apiops plan  --env prod ./apiops/**/*.yaml
      - run: apinizer apiops apply --env prod ./apiops/**/*.yaml
        env:
          APINIZER_TOKEN: ${{ secrets.APINIZER_TOKEN_PROD }}

Three meaningful properties of this pipeline:

  • Plan before apply. plan shows the diff before apply runs. A reviewer can look at the plan and approve or reject. The plan and apply use the same diff engine, so the plan reflects what apply will do.
  • Dev before prod. Dev runs unattended; prod requires manual approval. The pipeline structure enforces the order.
  • Tokens per environment. Each environment has its own credential. The dev token can't apply to prod. A compromised dev token doesn't reach prod.

The audit trail

Every apply lands in the same audit Elasticsearch index that records manual UI changes. The fields are the same:

  • Actor — the service account or human who applied
  • Timestamp
  • Entity — what was changed
  • Before / after — the diff
  • Environment — where it landed
  • Source — which pipeline or commit triggered the apply

A typical regulator question — "show me every change to the Payments APIs in Q4" — turns into one Elasticsearch query. The answer comes back in seconds. There's no "let me cross-reference Git, Jenkins, and the admin UI." The audit trail is unified.

What this lets developers do

The shift from console-driven to manifest-driven changes the developer's relationship with the platform.

Code review on API changes. A change to a rate-limit policy goes through the same review process as a code change. Reviewers see the diff. Comments live in the PR. History stays in Git.

Branch-per-feature. A new proxy ships on a feature branch. The branch's CI applies to a per-branch environment for testing. The PR merges, and the change lands in dev.

Rollback through Git. Revert the commit; reapply; done. The audit captures the revert as a normal apply.

Local validation. apinizer apiops validate runs locally. A developer catches a schema error before pushing.

What this lets operators do

The shift also changes how the operators run the platform.

Drift detection on a schedule. A nightly job runs apply in dry-run mode against prod and alerts if anything drifted from the manifest.

Environment cloning. A new staging environment provisions from the production manifests in minutes. The new environment is verifiably identical to prod where it should be, and explicitly different where it should be.

Multi-environment audit. "Show me every environment where the payments-default policy is applied." One query against the manifest repository.

Recovery posture. If the Manager is rebuilt from scratch, the manifests rebuild the platform state. The manifests are the durable artifact; the Manager's in-memory state is reproducible.

What APIops doesn't fix

Three things APIops doesn't make easier:

Bad API design. Manifests describe what's deployed; they don't make a poorly-designed API into a well-designed one.

The first migration. Moving from "everything is clicked in the admin UI" to "everything is in manifests" is a real migration. The Manager can export current state as manifests, which helps — but the team still has to organize them, parameterize them, and own them.

Skipping the platform team. APIops shifts work; it doesn't eliminate it. Someone still owns the manifest repository, reviews PRs, and operates the pipeline.

The shift, summarized

API platforms ran on admin UIs for a decade. That UI era is winding down. Platform engineers want manifests in Git, pipelines applying changes, and audit trails that match what they already have for infrastructure and application code.

APIops is the name for that shift. It is not a feature on a checklist. It is the operating model the platform converges to once enough of the work is in scope to make manual clicks untenable.

If your platform is mostly in the admin UI today, the conversation is worth having. We've helped a few customers migrate from "everything clicked" to "everything as manifests" — happy to share what the sequence looks like on a real cluster.


All posts · Book a Demo · Read the docs

© 2026 Apinizer. All rights reserved.