PS Product SecurityKnowledge Base

๐Ÿงพ API Definition Conformance Lab โ€” OpenAPI, Contract Linting, AuthZ Checks, and CI Validation

Intro: The most valuable API security lab is often not a scanner pointed at runtime. It is a disciplined workflow that treats the OpenAPI contract as a security-bearing artifact and continuously asks whether the implementation, authorization model, and release process still conform to it.

What this page includes

  • a hands-on learning path for OpenAPI security and conformance;
  • CLI examples using Redocly and optional 42Crunch-style audit flows;
  • examples for auth, authz, and schema-quality checks;
  • CI validation patterns for pull requests and release gates.

Why this lab is worth your time

A broken OpenAPI contract teaches three things at once:

  • design mistakes create runtime risk;
  • missing schema detail creates test blind spots;
  • missing auth or weak authz assumptions survive code review if the contract never made them explicit.

This maps directly to real Product Security review work.

Learning objectives

By the end of this lab you should be able to:

  1. lint an OpenAPI file for structural and quality issues;
  2. identify missing or weak security definitions;
  3. detect likely object-level or scope-level authorization gaps;
  4. fail a PR or release when the contract meaningfully regresses.

Lab workspace structure

openapi-lab/
  openapi/
    api.yaml
  redocly.yaml
  rules/
    custom-rules.yaml
  scripts/
    run-contract-checks.sh
  .github/workflows/
    openapi-governance.yml

Step 1 โ€” lint the contract with Redocly CLI

Install and run

npm install -g @redocly/cli
redocly lint openapi/api.yaml --extends recommended-strict --format codeframe

Example redocly.yaml

apis:
  core@v1:
    root: ./openapi/api.yaml

extends:
  - recommended

rules:
  operation-operationId: error
  operation-2xx-response: error
  security-defined: error
  no-server-example.com: off

What to look for

  • missing operationId values;
  • missing success response schemas;
  • routes with no security scheme when they should not be public;
  • ambiguous request/response definitions;
  • fields that should be constrained but are not.

Step 2 โ€” review the contract as a security artifact

For each sensitive route, ask:

  • what caller identity is expected?
  • what scope or role is required?
  • is object ownership implied or explicit?
  • are IDs and filters constrained enough to stop mass enumeration?
  • are server-generated fields protected from client override?

Example insecure pattern

paths:
  /v1/invoices/{invoiceId}:
    get:
      summary: Get invoice
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: invoiceId
          required: true
          schema:
            type: string

This says a token is needed, but says nothing about:

  • tenant ownership;
  • allowed roles;
  • admin-only exceptions;
  • object-level authorization expectations.

Better pattern with explicit reviewer notes

paths:
  /v1/invoices/{invoiceId}:
    get:
      operationId: getInvoice
      summary: Get one invoice owned by the authenticated tenant
      security:
        - bearerAuth: [invoices:read]
      parameters:
        - in: path
          name: invoiceId
          required: true
          schema:
            type: string
            pattern: '^[a-f0-9-]{36}$'
      responses:
        '200':
          description: Invoice returned only when the authenticated tenant owns the object
        '403':
          description: Authenticated caller lacks tenant or role entitlement
        '404':
          description: Object not found or intentionally hidden outside the tenant boundary

Step 3 โ€” add contract diff checks

Contract drift matters even when the file still parses.

Example breaking-change check idea

openapi-diff old-api.yaml new-api.yaml || true

Use this to review:

  • removed fields;
  • weakened constraints;
  • changed auth requirements;
  • response semantics that would break consumers or monitoring.

Step 4 โ€” optional 42Crunch audit flow

If you use 42Crunch or a similar platform, the learning goal is to compare:

  • what a contract security audit catches;
  • what your generic lint rules miss;
  • what should become part of your baseline API governance policy.

Example GitHub Actions job using 42Crunch action

name: openapi-security-audit
on:
  pull_request:
  push:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - name: 42Crunch API contract audit
        uses: 42Crunch/api-security-audit-action@v1
        with:
          api-token: ${{ secrets.FORTYTWOCRUNCH_TOKEN }}

Step 5 โ€” CI validation with comments and release gates

Example GitHub Actions workflow

name: openapi-governance
on:
  pull_request:
  push:
    branches: [main]

jobs:
  lint-contract:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install -g @redocly/cli
      - run: redocly lint openapi/api.yaml --extends recommended-strict --format github-actions

Example GitLab CI job

openapi_contract_lint:
  stage: security
  image: node:20-alpine
  script:
    - npm install -g @redocly/cli
    - redocly lint openapi/api.yaml --extends recommended-strict --format codeframe
  artifacts:
    when: always
    paths:
      - openapi/

Web UI flow for human review

If you use a platform UI such as 42Crunch:

  1. import the API contract;
  2. review score and issue classes;
  3. sort by auth, authz, and schema gaps first;
  4. tune policy thresholds for production-bound APIs;
  5. export the report or create tickets;
  6. record any exception with expiration and compensating controls.

What to document after the lab

Record:

  • the routes that lacked meaningful security semantics;
  • weak or missing schemas;
  • auth-only versus authz-aware routes;
  • the CI signal you would make blocking versus advisory;
  • one rule you would enforce everywhere.

Common mistakes

  • believing that โ€œhas bearer tokenโ€ means โ€œauthorization is designedโ€;
  • using contract lint only for syntax and not for security meaning;
  • failing to review drift between versions;
  • forgetting to tie audit results to release policy.

---Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.