Join our Newsletter — 33% off our NHI Course
Home› Guides› OpenAPI Specification Security Guide: Security Schemes, Contract Testing…
Guide Web & API Security

OpenAPI Specification Security Guide: Security Schemes, Contract Testing and Linting

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 15 min read
On this page

An OpenAPI description that says nothing true about authentication, limits or audience lets insecure endpoints ship without anyone noticing. The OpenAPI Specification (OAS) is the machine-readable contract behind most REST APIs, and the same file now drives gateway configuration, generated clients, documentation portals, fuzzers and API inventories. That makes it a security control in its own right: if the contract is accurate and linted, missing authentication and unbounded inputs are caught in a pull request; if it is stale or hand-waved, every downstream tool inherits the gap. This guide covers the OAS security model (Security Scheme and Security Requirement Objects in 3.1 and 3.2), linting with Spectral and the OWASP ruleset, contract and schema-based testing, protecting the description itself, and how to roll this out across many teams. It is written for API platform owners, AppSec engineers and developers who own OpenAPI files. For the wider programme, see the API Security Guide.

Key takeaways

  • Security declarations are claims, not enforcement. The security field documents what the API expects; only the gateway or application enforces it. Contract tests must prove the two agree.
  • Empty arrays and empty objects mean anonymous. An operation with security: [] removes the top-level requirement, and {} in the list makes authentication optional. Both should fail CI unless explicitly allowlisted.
  • Lint every description in the pipeline. Spectral's built-in oas ruleset plus the OWASP API Security ruleset catch unprotected write operations, API keys in URLs, plain HTTP servers and unbounded strings before review.
  • Bounded schemas are a security feature. maxLength, maxItems, integer format and maximum, and additionalProperties: false turn the contract into a validation policy the gateway can apply.
  • The description is sensitive. It maps every endpoint for an attacker. Publish internal descriptions only to authorised consumers, and treat third-party descriptions as untrusted input to your tooling.

What the OpenAPI security model can and cannot express

OAS describes security in two parts. A Security Scheme Object under components.securitySchemes defines how a caller authenticates. A Security Requirement Object, placed in the top-level security field or on an individual operation, says which schemes (and for OAuth 2.0 and OpenID Connect, which scopes) a request must satisfy. Version 3.2.0 is the current release of the specification; 3.1.x remains widely deployed, and the security objects are largely the same across both, with 3.2 adding the fields marked below.

Scheme typeKey fieldsSecurity notes
apiKeyname, in (query, header or cookie)Never in: query: keys end up in proxy logs, browser history and analytics. The OWASP REST Security Cheat Sheet advises not relying on API keys alone for sensitive or high-value resources.
httpscheme (IANA registered, case-insensitive), bearerFormatbearerFormat: JWT is a documentation hint only. basic is supported for compatibility; the specification states inclusion is not an endorsement.
mutualTLSdescriptionAdded in 3.1. Describe the issuing CA and expected certificate attributes in the description, because there are no structured fields for them.
oauth2flows (authorizationCode, clientCredentials, deviceAuthorization in 3.2, implicit, password), oauth2MetadataUrl in 3.2The specification points to the OAuth 2.0 Security BCP and recommends authorization code with PKCE. Do not declare implicit or password for new APIs.
openIdConnectopenIdConnectUrl (discovery document)Scopes in the requirement list are checked by the resource server, not by the description.

Three semantics cause most real-world mistakes:

  • Alternatives versus combinations: entries in the security array are alternatives (any one satisfies the request). Schemes listed inside one Security Requirement Object must all be satisfied. Writing [{apiKey: []}, {oauth: [write]}] when you meant both is a silent downgrade.
  • Overrides: operation-level security replaces the top-level value entirely. An empty array removes it; an empty object {} in the list declares anonymous access as an option.
  • Deprecation: 3.2 adds deprecated: true on a Security Scheme Object, which lets you signal a scheme migration (for example API key to OAuth) in the contract itself.

The specification's own security considerations add two points for tool builders: resolution of a Security Requirement to a scheme in multi-document descriptions is ambiguous in a way that can be abused (a component name identical to a URI wins over URI resolution), and descriptions can reference external resources that tools dereference automatically. Keep security schemes in the entry document and disable remote $ref resolution in CI unless the target is pinned and trusted.

Designing a secure contract

A contract that the gateway can enforce needs more than authentication. Treat these as the minimum for every operation:

  • Authentication on every write: every POST, PUT, PATCH and DELETE has a non-empty Security Requirement. Public reads are listed by exception, with an x- extension recording who approved them.
  • Scopes that match functions: separate read and write scopes, and give administrative operations a different scheme or scope from user operations, so broken function-level authorisation (API5:2023) is visible in the contract.
  • Unguessable identifiers: path parameters such as {orderId} typed as string with format: uuid rather than sequential integers. This does not replace object-level checks (API1:2023), it just removes the easy enumeration.
  • Bounded inputs: strings with maxLength, enum or pattern; arrays with maxItems; integers with format (int32, int64) and minimum/maximum. These are the inputs to API4:2023 resource consumption controls.
  • Closed objects for writes: request bodies with additionalProperties: false and separate read and write schemas (or readOnly/writeOnly) so mass assignment and excessive data exposure (API3:2023) are blocked by schema validation.
  • Documented errors and limits: 401, 403, 429 and 500 responses with a fixed error schema (RFC 9457 problem details is a common choice), plus rate limit and Retry-After headers on 429.
  • Explicit audience: every servers entry uses https:// and declares whether it is internal, so inventory tooling can separate partner, public and internal surfaces (API9:2023).

OWASP ASVS 5.0 backs this up from the verification side: V4.1.4 requires that only explicitly supported HTTP methods are accepted, V8.1.1 and V8.1.2 require documented function-level and field-level authorisation rules, and V13.4.5 requires that internal API documentation and monitoring endpoints are not exposed unless intended. A well-annotated OpenAPI file is the most practical place to keep that documentation. For token design behind the bearer scheme, see the JWT Security Guide.

Linting OpenAPI with Spectral and the OWASP ruleset

Spectral is an open source JSON and YAML linter with a built-in oas ruleset. Stoplight also publishes @stoplight/spectral-owasp-ruleset, whose v2.x is based on the OWASP API Security Top 10 2023 (v1.x targeted the 2019 edition). A project extends it with a one-line .spectral.yaml (extends: ["@stoplight/spectral-owasp-ruleset"]) and runs spectral lint against the description. The ruleset's own documentation is clear about the limit: it reads only the described surface, not the code behind it.

RuleWhat it flagsOWASP API risk
oas3-operation-security-defined (built-in)Operation security names a scheme not defined in components.securitySchemesAPI2 Broken Authentication
no-script-tags-in-markdown, no-eval-in-markdown (built-in)Script or eval( in descriptions that may be rendered into HTML documentationTooling risk (XSS in portals)
owasp:api2:2023-write-restrictedWrite operations with no security schemeAPI2
owasp:api2:2023-read-restrictedRead operations with no security scheme (information severity)API2
owasp:api2:2023-no-api-keys-in-urlapiKey schemes placed in the query or pathAPI2
owasp:api2:2023-auth-insecure-schemes, owasp:api2:2023-no-http-basicOutdated HTTP schemes such as NTLM or OAuth 1, and HTTP BasicAPI2
owasp:api2:2023-short-lived-access-tokensOAuth flows (other than client credentials) with no refreshUrl, implying long-lived access tokensAPI2
owasp:api1:2023-no-numeric-idsID parameters typed as integersAPI1 BOLA
owasp:api4:2023-string-limit, array-limit, integer-limitUnbounded strings, arrays and integersAPI4 Unrestricted Resource Consumption
owasp:api4:2023-rate-limit, rate-limit-responses-4292XX and 4XX responses with no rate limit headers; missing 429API4
owasp:api5:2023-admin-security-uniqueAdmin paths sharing the same security scheme as normal pathsAPI5 BFLA
owasp:api8:2023-no-server-http, define-cors-origin, define-error-responses-401Plain HTTP servers, missing CORS declaration, undefined 401 and 500 responsesAPI8 Security Misconfiguration
owasp:api9:2023-inventory-access, inventory-environmentServers without an x-internal audience flag or environment labelAPI9 Improper Inventory Management

Rule IDs use the ruleset's own naming, which in places differs from the Top 10 numbering (the inventory rule is reported as api8 in some example output and defined as api9 in the source). Pin the ruleset version, and map findings by the rule ID your pinned version emits. Use overrides in your local ruleset to downgrade a rule for a specific path with a recorded reason, rather than disabling it globally.

Contract testing: proving the description matches the running API

Linting checks the document; it cannot see whether DELETE /accounts/{id} actually rejects an unauthenticated call. Schema-driven testing closes that gap by generating requests from the description and comparing responses with it.

TechniqueWhat it provesExample toolingWhere to run
Negative authentication testsEvery operation with a Security Requirement returns 401 without credentials and 403 with insufficient scopeGenerated test suite from the description, Schemathesis per-scheme authCI against an ephemeral environment
Response conformanceResponses match documented schemas; no undeclared fields (data exposure) or stack tracesSchemathesis checks, gateway response validationCI and staging
Property-based and stateful fuzzingEdge-case inputs do not cause 500s; chained operations do not leak other users' objectsSchemathesis stateful mode, Microsoft RESTler checkersStaging only
Breaking change diffA pull request does not silently drop a security requirement or widen a schemaSpec diff tools in CI, custom Spectral rulesPull request
Drift detectionTraffic matches the published contract; undocumented endpoints are surfacedGateway logs or API discovery compared with the registryProduction, passively

Schemathesis states in its own documentation that it sends real requests that create, change and delete data and should be pointed at development or staging, not production. RESTler describes itself as a stateful REST API fuzzer that compiles the description into a grammar and runs checkers for logic bugs such as resource leaks and hierarchy violations. Both are authorised-testing tools: run them against environments you own, with test accounts, and with rate limits set. For the fuzzing discipline itself, see the Fuzzing Guide.

Where identity fits: credentials in descriptions and test pipelines

OpenAPI work creates its own non-human identities. Contract test runners need API keys, client credentials or test user tokens for every scheme; documentation portals with "try it out" consoles hold OAuth client registrations; and generated SDKs often ship with example keys that were real once.

  • Test credentials: issue dedicated, scoped client credentials per environment for contract testing, stored in the pipeline's secret store and rotated on a schedule. Never put working values in example or examples fields.
  • Portal clients: register "try it out" consoles as public OAuth clients using authorization code with PKCE, with redirect URIs locked to the portal domain.
  • Machine callers: describe machine-to-machine operations with clientCredentials or mutualTLS rather than shared API keys, so each calling workload has its own identity. See the mTLS Guide.

Protecting and governing the description itself

The OWASP API Security Top 10 2023 entry for improper inventory management (API9) lists missing or outdated documentation as a "documentation blindspot" and recommends generating documentation from open standards in CI/CD and making it available only to those authorised to use the API. The OAS security considerations note that a Paths Object may be present but empty, so a portal can expose the Info Object to unauthenticated viewers while hiding operations.

  • Single source of truth: store each description in the service repository, generate it from code or validate code against it, and publish to a registry from CI only. Hand-copied descriptions drift.
  • Visibility tiers: public, partner and internal descriptions published from the same source with internal operations filtered out by tag or x-internal, not maintained as separate files.
  • Do not serve internal specs from production: framework defaults often expose /openapi.json, /swagger-ui or /docs. Disable them on internet-facing hosts or put them behind authentication. The FastAPI Security Guide covers one common case.
  • Untrusted descriptions: when importing a partner's description into a gateway or code generator, lint it first (including the markdown rules), disable remote references and review generated code like any third-party dependency.

Rolling out contract-first API security

  1. Inventory: collect every OpenAPI description from repositories, gateways and portals into one registry; record APIs with no description as findings (API9).
  2. Baseline lint in report-only mode: run Spectral with oas and the OWASP ruleset across the registry, publish counts per team and agree a severity policy. Nothing blocks yet.
  3. Block new violations: fail pull requests on new errors only (missing write security, API keys in URLs, HTTP servers, undefined schemes). Existing findings go to a backlog with owners.
  4. Enforce from the contract: import descriptions into the gateway for request validation and authentication policy, starting with one API in monitor mode, then enforce. See the API Gateway Security Guide.
  5. Add contract tests: negative authentication tests for every secured operation, then response conformance, then stateful fuzzing in staging.
  6. Close the loop with runtime: compare gateway traffic with the registry weekly and open tickets for undocumented endpoints.

Rollback: keep gateway validation behind a per-API flag so a schema error that blocks legitimate traffic can be switched to monitor mode in minutes, and fix the description rather than the gateway rule.

Small versus large organisations: a small team can get most of the value from the OWASP ruleset in CI and a short list of negative authentication tests. A large estate needs a central registry, a shared organisational ruleset that extends the OWASP one with house rules (naming, error schema, required x-owner extension), and a platform team that owns the gateway import path.

Detection and measurement

  • Log: gateway request validation failures by operation, 401 and 403 rates per operation, requests to paths not in the registry, and hits on documentation endpoints from outside expected networks.
  • Metric: percentage of production APIs with a registered, linted description (target 100% for internet-facing).
  • Metric: number of operations with no security requirement that are not on the approved public list (target zero).
  • Metric: open OWASP ruleset errors per API and their trend.
  • Metric: percentage of secured operations covered by an automated negative authentication test.
  • Metric: undocumented endpoints observed in traffic per month, and median time to document or retire them.

Framework mapping

FrameworkReferenceHow OpenAPI security supports it
OWASP API Security Top 10 2023API1, API2, API3, API4, API5, API8, API9Lint rules and schema constraints map directly (see the linting table)
OWASP ASVS 5.0V4.1.4, V8.1.1, V8.1.2, V13.4.5Allowed methods, documented authorisation rules, unexposed internal documentation
NIST CSF 2.0ID.AM-02, PR.PS-06Inventory of services; secure development integrated into the SDLC
NIST SP 800-53 Rev. 5CM-8, SA-11, SA-15Component inventory; developer testing; development standards and tools
ISO/IEC 27001:2022 Annex AA.8.25, A.8.28, A.8.29Secure development life cycle, secure coding, security testing in development
MITRE ATT&CKT1190 Exploit Public-Facing ApplicationUnauthenticated or unvalidated endpoints are the entry point this technique describes

Common failure patterns

  • Public documentation, unauthenticated endpoints: in the McKinsey Lilli incident, the researchers report finding API documentation for more than 200 endpoints publicly exposed, 22 of which accepted requests without authentication; one of those had a SQL injection flaw. A lint gate on unsecured operations and an access-controlled documentation portal address both halves.
  • Security declared globally, removed locally: a developer adds security: [] to one operation to make a health check work, and the same edit is copied to a data endpoint. Allowlist anonymous operations by ID.
  • Contract and code disagree: the description says OAuth with a write scope, the handler checks only that a token exists. Only negative contract tests catch this.
  • Unbounded schemas imported into the gateway: validation passes everything because no string has a maxLength and objects accept additional properties.
  • Swagger UI left on in production: framework default documentation endpoints expose internal and deprecated operations, feeding API9 shadow and zombie API problems.
  • Real keys in examples: working API keys or tokens pasted into example fields and published to a portal or SDK. Scan descriptions with the same secret scanning as code.

Practitioner checklist

  • Every API has one OpenAPI description in its repository, published to a central registry from CI.
  • Spectral runs with the built-in oas ruleset and a pinned version of the OWASP API Security ruleset on every pull request.
  • No write operation lacks a Security Requirement; anonymous operations are on an approved list.
  • No apiKey scheme uses in: query; no implicit or password OAuth flows on new APIs.
  • Strings, arrays and integers are bounded; write bodies use additionalProperties: false.
  • 401, 403, 429 and 500 responses are defined with a fixed error schema.
  • Negative authentication tests exist for every secured operation; fuzzing runs only in staging with test identities.
  • Internal descriptions and documentation UIs are not reachable from the internet without authentication.
  • Third-party descriptions are linted and remote references disabled before import.
  • Gateway traffic is compared with the registry and undocumented endpoints are ticketed.

Standards and references

Related NHI Mgmt Group resources: API Security Guide · API Gateway Security Guide · Top 10 API Security Risks · Rate Limiting and API Abuse Guide · JWT Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.