Censys · API Governance Rules

Censys API Rules

Spectral linting rules defining API design standards and conventions for Censys.

31 Rules error 8 warn 22 info 1
View Rules File View on GitHub

Rule Categories

deprecated info openapi operation parameter paths requestbody response schema security servers tag tags

Rules

warn
info-title-censys-prefix
API title must start with "Censys".
$.info.title
warn
info-description-required
API info.description is required.
$.info
error
info-version-required
API info.version is required.
$.info
warn
openapi-version-3-1
Censys APIs target OpenAPI 3.1.
$
error
servers-required
At least one server must be defined.
$
error
servers-https
Server URLs must use HTTPS.
$.servers[*].url
warn
servers-censys-host
Server URL should be a censys.io domain.
$.servers[*].url
warn
paths-kebab-case
Path segments should be kebab-case (or path parameters).
$.paths.*~
error
paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths.*~
warn
paths-version-prefix
Censys paths must include a /v{n} or /api/v{n} version prefix.
$.paths.*~
error
operation-operationid-required
Every operation must have an operationId.
$.paths.*[get,post,put,patch,delete]
warn
operation-operationid-kebab
operationId should be kebab-case (Censys convention).
$.paths.*[get,post,put,patch,delete].operationId
error
operation-summary-required
Every operation must have a summary.
$.paths.*[get,post,put,patch,delete]
warn
operation-summary-title-case
Operation summary should be Title Case prefixed with "Censys".
$.paths.*[get,post,put,patch,delete].summary
warn
operation-description-required
Every operation should have a description.
$.paths.*[get,post,put,patch,delete]
warn
operation-tags-required
Every operation must declare at least one tag.
$.paths.*[get,post,put,patch,delete]
warn
tags-global-defined
Top-level tags array should be defined.
$
warn
tag-title-case
Tags should be Title Case (e.g. "Threat Hunting").
$.tags[*].name
warn
parameter-description-required
Parameters should have a description.
$.paths.*[get,post,put,patch,delete].parameters[*]
warn
parameter-snake-case
Parameter names should be snake_case (Censys convention).
$.paths.*[get,post,put,patch,delete].parameters[*].name
error
parameter-no-auth-query
Authentication tokens must not be sent in query parameters.
$.paths.*[get,post,put,patch,delete].parameters[?(@.in=='query')].name
warn
requestbody-json-content
Request bodies must offer application/json content.
$.paths.*[post,put,patch].requestBody.content
error
response-2xx-required
Operations must define at least one 2xx response.
$.paths.*[get,post,put,patch,delete].responses
warn
response-401-defined
Authenticated operations should document a 401 response.
$.paths.*[get,post,put,patch,delete].responses
info
response-429-defined
Operations should document a 429 rate-limit response.
$.paths.*[get,post,put,patch,delete].responses
warn
response-json-content
2xx responses should offer application/json content.
$.paths.*[get,post,put,patch,delete].responses[?(@property.match(/^2[0-9][0-9]$/))].content
warn
schema-property-snake-case
Schema properties must be snake_case.
$.components.schemas.*.properties.*~
warn
schema-type-required
Schemas must declare type or composition (oneOf/anyOf/allOf/$ref).
$.components.schemas.*
warn
security-personal-access-token-defined
PersonalAccessToken security scheme must be defined.
$.components.securitySchemes
warn
security-bearer-scheme
PersonalAccessToken must be HTTP bearer.
$.components.securitySchemes.PersonalAccessToken
warn
deprecated-documented
Deprecated operations should document migration in description.
$.paths.*[?(@.deprecated==true)]

Spectral Ruleset

Raw ↑
# Censys API Spectral Ruleset
# Generated 2026-05-29 from analysis of openapi/censys-platform-openapi.yml and openapi/censys-asset-graph-openapi.yml
# Enforces Censys's OpenAPI 3.1, snake_case schema properties, /v{n} versioning, PersonalAccessToken bearer auth,
# Personal Access Token security, and Title Case operation summaries prefixed with "Censys".

extends: [[spectral:oas, recommended]]

rules:

  # ── INFO / METADATA ────────────────────────────────────────────────
  info-title-censys-prefix:
    description: API title must start with "Censys".
    given: $.info.title
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^Censys"
  info-description-required:
    description: API info.description is required.
    given: $.info
    severity: warn
    then:
      field: description
      function: truthy
  info-version-required:
    description: API info.version is required.
    given: $.info
    severity: error
    then:
      field: version
      function: truthy

  # ── OPENAPI VERSION ────────────────────────────────────────────────
  openapi-version-3-1:
    description: Censys APIs target OpenAPI 3.1.
    given: $
    severity: warn
    then:
      field: openapi
      function: pattern
      functionOptions:
        match: "^3\\.1"

  # ── SERVERS ────────────────────────────────────────────────────────
  servers-required:
    description: At least one server must be defined.
    given: $
    severity: error
    then:
      field: servers
      function: truthy
  servers-https:
    description: Server URLs must use HTTPS.
    given: $.servers[*].url
    severity: error
    then:
      function: pattern
      functionOptions:
        match: "^https://"
  servers-censys-host:
    description: Server URL should be a censys.io domain.
    given: $.servers[*].url
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "censys\\.io"

  # ── PATHS ──────────────────────────────────────────────────────────
  paths-kebab-case:
    description: Path segments should be kebab-case (or path parameters).
    given: $.paths.*~
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^(/(v\\d+|api)?(/[a-z0-9-]+|/\\{[a-zA-Z0-9_]+\\})*)+/?$"
  paths-no-trailing-slash:
    description: Paths must not end with a trailing slash.
    given: $.paths.*~
    severity: error
    then:
      function: pattern
      functionOptions:
        notMatch: ".+/$"
  paths-version-prefix:
    description: Censys paths must include a /v{n} or /api/v{n} version prefix.
    given: $.paths.*~
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^/(v\\d+|api/v\\d+)"

  # ── OPERATIONS ─────────────────────────────────────────────────────
  operation-operationid-required:
    description: Every operation must have an operationId.
    given: $.paths.*[get,post,put,patch,delete]
    severity: error
    then:
      field: operationId
      function: truthy
  operation-operationid-kebab:
    description: operationId should be kebab-case (Censys convention).
    given: $.paths.*[get,post,put,patch,delete].operationId
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[a-z0-9]+(-[a-z0-9]+)*$"
  operation-summary-required:
    description: Every operation must have a summary.
    given: $.paths.*[get,post,put,patch,delete]
    severity: error
    then:
      field: summary
      function: truthy
  operation-summary-title-case:
    description: Operation summary should be Title Case prefixed with "Censys".
    given: $.paths.*[get,post,put,patch,delete].summary
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^Censys "
  operation-description-required:
    description: Every operation should have a description.
    given: $.paths.*[get,post,put,patch,delete]
    severity: warn
    then:
      field: description
      function: truthy
  operation-tags-required:
    description: Every operation must declare at least one tag.
    given: $.paths.*[get,post,put,patch,delete]
    severity: warn
    then:
      field: tags
      function: schema
      functionOptions:
        schema:
          type: array
          minItems: 1

  # ── TAGS ───────────────────────────────────────────────────────────
  tags-global-defined:
    description: Top-level tags array should be defined.
    given: $
    severity: warn
    then:
      field: tags
      function: truthy
  tag-title-case:
    description: Tags should be Title Case (e.g. "Threat Hunting").
    given: $.tags[*].name
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[A-Z][A-Za-z0-9]*( [A-Za-z0-9]+)*$"

  # ── PARAMETERS ─────────────────────────────────────────────────────
  parameter-description-required:
    description: Parameters should have a description.
    given: $.paths.*[get,post,put,patch,delete].parameters[*]
    severity: warn
    then:
      field: description
      function: truthy
  parameter-snake-case:
    description: Parameter names should be snake_case (Censys convention).
    given: $.paths.*[get,post,put,patch,delete].parameters[*].name
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-z0-9_]*$"
  parameter-no-auth-query:
    description: Authentication tokens must not be sent in query parameters.
    given: $.paths.*[get,post,put,patch,delete].parameters[?(@.in=='query')].name
    severity: error
    then:
      function: pattern
      functionOptions:
        notMatch: "(?i)(api[_-]?key|access[_-]?token|bearer)"

  # ── REQUEST BODIES ─────────────────────────────────────────────────
  requestbody-json-content:
    description: Request bodies must offer application/json content.
    given: $.paths.*[post,put,patch].requestBody.content
    severity: warn
    then:
      field: application/json
      function: truthy

  # ── RESPONSES ──────────────────────────────────────────────────────
  response-2xx-required:
    description: Operations must define at least one 2xx response.
    given: $.paths.*[get,post,put,patch,delete].responses
    severity: error
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          patternProperties:
            "^2[0-9][0-9]$": {}
          minProperties: 1
  response-401-defined:
    description: Authenticated operations should document a 401 response.
    given: $.paths.*[get,post,put,patch,delete].responses
    severity: warn
    then:
      field: '401'
      function: truthy
  response-429-defined:
    description: Operations should document a 429 rate-limit response.
    given: $.paths.*[get,post,put,patch,delete].responses
    severity: info
    then:
      field: '429'
      function: truthy
  response-json-content:
    description: 2xx responses should offer application/json content.
    given: $.paths.*[get,post,put,patch,delete].responses[?(@property.match(/^2[0-9][0-9]$/))].content
    severity: warn
    then:
      field: application/json
      function: truthy

  # ── SCHEMAS ────────────────────────────────────────────────────────
  schema-property-snake-case:
    description: Schema properties must be snake_case.
    given: $.components.schemas.*.properties.*~
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-z0-9_]*$"
  schema-type-required:
    description: Schemas must declare type or composition (oneOf/anyOf/allOf/$ref).
    given: $.components.schemas.*
    severity: warn
    then:
      function: schema
      functionOptions:
        schema:
          anyOf:
            - required: [type]
            - required: [oneOf]
            - required: [anyOf]
            - required: [allOf]
            - required: ["$ref"]

  # ── SECURITY ───────────────────────────────────────────────────────
  security-personal-access-token-defined:
    description: PersonalAccessToken security scheme must be defined.
    given: $.components.securitySchemes
    severity: warn
    then:
      field: PersonalAccessToken
      function: truthy
  security-bearer-scheme:
    description: PersonalAccessToken must be HTTP bearer.
    given: $.components.securitySchemes.PersonalAccessToken
    severity: warn
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          properties:
            type: { const: http }
            scheme: { const: bearer }
          required: [type, scheme]

  # ── GENERAL QUALITY ────────────────────────────────────────────────
  deprecated-documented:
    description: Deprecated operations should document migration in description.
    given: $.paths.*[?(@.deprecated==true)]
    severity: warn
    then:
      field: description
      function: truthy