Skip to content

Instantly share code, notes, and snippets.

@mcarbonneaux
Last active May 29, 2025 13:42
Show Gist options
  • Save mcarbonneaux/2b92761b13e17e46c20e34e9de5771a9 to your computer and use it in GitHub Desktop.
Save mcarbonneaux/2b92761b13e17e46c20e34e9de5771a9 to your computer and use it in GitHub Desktop.

Revisions

  1. mcarbonneaux revised this gist May 29, 2025. No changes.
  2. mcarbonneaux revised this gist May 29, 2025. 1 changed file with 0 additions and 50 deletions.
    50 changes: 0 additions & 50 deletions smallstep-api.swagger
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,3 @@
    # Smallstep Certificates API - Swagger Documentation

    ```yaml
    openapi: 3.0.3
    info:
    title: Smallstep Certificates API
    @@ -696,50 +693,3 @@ tags:
    externalDocs:
    description: Smallstep Certificates Documentation
    url: https://smallstep.com/docs/step-ca/
    ```

    ## Usage Examples

    ### Basic Certificate Signing
    ```bash
    # Get a one-time token
    step ca token example.com

    # Sign a certificate
    curl -X POST https://ca.example.com:9000/1.0/sign \
    -H "Content-Type: application/json" \
    -d '{
    "csr": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----",
    "ott": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    }'
    ```

    ### Health Check
    ```bash
    curl https://ca.example.com:9000/1.0/health
    ```

    ### Get Root Certificate
    ```bash
    curl https://ca.example.com:9000/1.0/roots
    ```

    ### SSH Certificate Signing
    ```bash
    curl -X POST https://ca.example.com:9000/1.0/ssh/sign \
    -H "Content-Type: application/json" \
    -d '{
    "publicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...",
    "ott": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
    "certType": "user",
    "principals": ["alice", "bob"]
    }'
    ```

    ## Notes

    This Swagger documentation is based on the smallstep/certificates API structure. The actual implementation may have additional endpoints or slight variations. For the most up-to-date information, refer to:

    - [Smallstep Certificates GitHub Repository](https://github.com/smallstep/certificates)
    - [Official Documentation](https://smallstep.com/docs/step-ca/)
    - [API Client Examples](https://github.com/smallstep/clients)
  3. mcarbonneaux revised this gist May 29, 2025. 1 changed file with 415 additions and 848 deletions.
    1,263 changes: 415 additions & 848 deletions smallstep-api.swagger
    Original file line number Diff line number Diff line change
    @@ -1,90 +1,182 @@
    # Smallstep Certificates API - Swagger Documentation

    ```yaml
    openapi: 3.0.3
    info:
    title: Smallstep Certificates API
    description: |
    REST API for Smallstep Certificates - A private certificate authority (X.509 & SSH) & ACME server
    for secure automated certificate management.
    A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management.

    This API allows you to:
    - Sign certificate requests
    - Revoke certificates
    - Renew certificates
    - Get CA roots and federation
    - Manage SSH certificates
    - Issue and manage X.509 TLS certificates
    - Handle SSH certificates
    - Manage certificate renewal and revocation
    - Perform health checks and get CA information

    ## Authentication
    Most endpoints require JWT token authentication or mTLS client certificates.

    Authentication is typically done using JWT tokens or provisioner-specific authentication methods.
    version: 1.0.0
    ## Base URL Structure
    The API is typically served on `https://your-ca-server:port/1.0/`
    version: "1.0"
    contact:
    name: Smallstep
    url: https://github.com/smallstep/certificates
    name: Smallstep Labs
    url: https://smallstep.com
    license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
    url: https://github.com/smallstep/certificates/blob/master/LICENSE

    servers:
    - url: https://localhost:9000
    description: Default step-ca server
    - url: https://ca.example.com
    - url: https://localhost:9000/1.0
    description: Default local step-ca server
    - url: https://ca.example.com/1.0
    description: Production CA server

    security:
    - BearerAuth: []
    - mTLS: []

    paths:
    /1.0/sign:
    /health:
    get:
    summary: Health Check
    description: Check the health status of the CA server
    operationId: getHealth
    tags:
    - Health
    security: []
    responses:
    '200':
    description: CA server is healthy
    content:
    application/json:
    schema:
    type: object
    properties:
    status:
    type: string
    example: "ok"
    time:
    type: string
    format: date-time
    '500':
    $ref: '#/components/responses/InternalServerError'

    /root/{fingerprint}:
    get:
    summary: Get Root Certificate
    description: Retrieve the root certificate by fingerprint
    operationId: getRootCertificate
    tags:
    - Certificates
    security: []
    parameters:
    - name: fingerprint
    in: path
    required: true
    description: SHA256 fingerprint of the root certificate
    schema:
    type: string
    example: "a1b2c3d4e5f6..."
    responses:
    '200':
    description: Root certificate in PEM format
    content:
    application/pem-certificate-chain:
    schema:
    type: string
    format: binary
    example: |
    -----BEGIN CERTIFICATE-----
    MIIBkTCB+wIJAK...
    -----END CERTIFICATE-----
    '404':
    $ref: '#/components/responses/NotFound'

    /roots:
    get:
    summary: Get Root Certificates
    description: Retrieve all root certificates
    operationId: getRootCertificates
    tags:
    - Certificates
    security: []
    responses:
    '200':
    description: List of root certificates
    content:
    application/json:
    schema:
    type: object
    properties:
    crts:
    type: array
    items:
    type: string
    description: PEM-encoded certificate
    example: |
    -----BEGIN CERTIFICATE-----
    MIIBkTCB+wIJAK...
    -----END CERTIFICATE-----

    /sign:
    post:
    summary: Sign a certificate signing request
    summary: Sign Certificate Request
    description: |
    Signs a Certificate Signing Request (CSR) and returns a signed certificate.
    Requires proper authentication via JWT token or other provisioner methods.
    Sign a Certificate Signing Request (CSR) and return a signed certificate.
    This is the primary endpoint for certificate issuance.
    operationId: signCertificate
    tags:
    - Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignRequest'
    example:
    csr: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    notAfter: "2024-12-31T23:59:59Z"
    notBefore: "2024-01-01T00:00:00Z"
    examples:
    basic_tls:
    summary: Basic TLS Certificate Request
    value:
    csr: "-----BEGIN CERTIFICATE REQUEST-----\nMIICWjCCAUICAQAwFTETMBEGA1UEAwwKZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3\n..."
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    with_provisioner:
    summary: Request with Specific Provisioner
    value:
    csr: "-----BEGIN CERTIFICATE REQUEST-----\nMIICWjCCAUICAQAwFTETMBEGA1UEAwwKZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3\n..."
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    provisioner: "my-provisioner"
    responses:
    '200':
    '201':
    description: Certificate successfully signed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignResponse'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    certChain: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/renew:
    /renew:
    post:
    summary: Renew a certificate
    summary: Renew Certificate
    description: |
    Renews an existing certificate. The request must include the current certificate
    and proper authentication.
    Renew an existing certificate. The request must be authenticated with the
    current certificate that needs to be renewed.
    operationId: renewCertificate
    tags:
    - Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RenewRequest'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    responses:
    '200':
    '201':
    description: Certificate successfully renewed
    content:
    application/json:
    @@ -94,171 +186,116 @@ paths:
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/revoke:
    /revoke:
    post:
    summary: Revoke a certificate
    description: |
    Revokes a certificate using either the certificate itself or its serial number.
    Requires proper authentication and authorization.
    summary: Revoke Certificate
    description: Revoke a certificate using its serial number or certificate PEM
    operationId: revokeCertificate
    tags:
    - Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeRequest'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    reason: "cessationOfOperation"
    reasonCode: 5
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    responses:
    '200':
    description: Certificate successfully revoked
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeResponse'
    example:
    status: "ok"
    type: object
    properties:
    status:
    type: string
    example: "ok"
    message:
    type: string
    example: "Certificate revoked"
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/roots:
    get:
    summary: Get CA root certificates
    description: |
    Returns the root certificates of the Certificate Authority.
    This endpoint is typically public and doesn't require authentication.
    operationId: getRoots
    responses:
    '200':
    description: Root certificates retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RootsResponse'
    example:
    roots: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/federation:
    get:
    summary: Get federation certificates
    description: |
    Returns the federated root certificates that this CA trusts.
    Used for cross-CA certificate validation.
    operationId: getFederation
    responses:
    '200':
    description: Federation certificates retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/FederationResponse'
    example:
    federated: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/health:
    get:
    summary: Health check
    description: Returns the health status of the CA server
    operationId: getHealth
    responses:
    '200':
    description: Server is healthy
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/HealthResponse'
    example:
    status: "ok"
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/version:
    /provisioners:
    get:
    summary: Get version information
    description: Returns version information about the CA server
    operationId: getVersion
    summary: List Provisioners
    description: Get list of configured provisioners
    operationId: getProvisioners
    tags:
    - Provisioners
    parameters:
    - name: cursor
    in: query
    description: Pagination cursor
    schema:
    type: string
    - name: limit
    in: query
    description: Maximum number of items to return
    schema:
    type: integer
    minimum: 1
    maximum: 100
    default: 20
    responses:
    '200':
    description: Version information retrieved successfully
    description: List of provisioners
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/VersionResponse'
    example:
    version: "0.25.0"
    require_client_authentication: true

    /1.0/ssh/sign:
    type: object
    properties:
    provisioners:
    type: array
    items:
    $ref: '#/components/schemas/Provisioner'
    nextCursor:
    type: string
    description: Cursor for next page

    /ssh/sign:
    post:
    summary: Sign SSH certificate
    description: |
    Signs an SSH certificate request and returns a signed SSH certificate.
    Used for SSH certificate-based authentication.
    summary: Sign SSH Certificate
    description: Sign an SSH public key and return an SSH certificate
    operationId: signSSHCertificate
    tags:
    - SSH Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    certType: "user"
    keyID: "[email protected]"
    principals: ["user", "admin"]
    validAfter: "2024-01-01T00:00:00Z"
    validBefore: "2024-12-31T23:59:59Z"
    responses:
    '200':
    '201':
    description: SSH certificate successfully signed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignResponse'
    example:
    certificate: "[email protected] AAAAHHNzaC1..."
    identityID: "[email protected]"
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/renew:
    /ssh/renew:
    post:
    summary: Renew SSH certificate
    description: Renews an existing SSH certificate
    summary: Renew SSH Certificate
    description: Renew an existing SSH certificate
    operationId: renewSSHCertificate
    tags:
    - SSH Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRenewRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    responses:
    '200':
    '201':
    description: SSH certificate successfully renewed
    content:
    application/json:
    @@ -268,339 +305,106 @@ paths:
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/revoke:
    /ssh/revoke:
    post:
    summary: Revoke SSH certificate
    description: Revokes an SSH certificate
    summary: Revoke SSH Certificate
    description: Revoke an SSH certificate
    operationId: revokeSSHCertificate
    tags:
    - SSH Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRevokeRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    serial: "1234567890"
    responses:
    '200':
    description: SSH certificate successfully revoked
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'
    type: object
    properties:
    status:
    type: string
    example: "ok"

    /1.0/ssh/roots:
    /ssh/config:
    get:
    summary: Get SSH CA public keys
    description: Returns the SSH CA public keys for host and user certificates
    operationId: getSSHRoots
    responses:
    '200':
    description: SSH roots retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRootsResponse'
    example:
    hostKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    userKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/config:
    post:
    summary: Get SSH client configuration
    description: Returns SSH client configuration for the given host
    summary: Get SSH Configuration
    description: Get SSH configuration for clients
    operationId: getSSHConfig
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHConfigRequest'
    example:
    type: "host"
    hostname: "example.com"
    responses:
    '200':
    description: SSH configuration retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHConfigResponse'
    example:
    config: "Host example.com\n HostKeyAlgorithms..."
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    /provisioners:
    get:
    summary: Get all provisioners
    description: |
    Returns a list of all configured provisioners on the CA.
    This endpoint is typically used to discover available provisioners and their capabilities.
    operationId: getProvisioners
    tags:
    - SSH Certificates
    parameters:
    - name: cursor
    - name: type
    in: query
    description: Cursor for pagination
    required: false
    description: Configuration type (user or host)
    schema:
    type: string
    - name: limit
    enum: [user, host]
    default: user
    - name: template
    in: query
    description: Maximum number of provisioners to return
    required: false
    schema:
    type: integer
    default: 20
    maximum: 100
    responses:
    '200':
    description: Provisioners retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/ProvisionersResponse'
    example:
    provisioners:
    - id: "acme"
    name: "ACME"
    type: "ACME"
    encryptedKey: ""
    claims:
    minTLSCertDuration: "5m"
    maxTLSCertDuration: "24h"
    defaultTLSCertDuration: "24h"
    - id: "jwk-provisioner"
    name: "JWK"
    type: "JWK"
    key:
    kty: "EC"
    crv: "P-256"
    x: "..."
    y: "..."
    encryptedKey: "..."
    nextCursor: ""
    '500':
    $ref: '#/components/responses/InternalError'

    /provisioners/{provisionerID}:
    get:
    summary: Get provisioner by ID
    description: Returns detailed information about a specific provisioner
    operationId: getProvisionerByID
    parameters:
    - name: provisionerID
    in: path
    required: true
    description: ID of the provisioner
    schema:
    type: string
    example: "acme"
    responses:
    '200':
    description: Provisioner retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Provisioner'
    '404':
    $ref: '#/components/responses/NotFound'
    '500':
    $ref: '#/components/responses/InternalError'

    /root/{sha}:
    get:
    summary: Get root certificate by SHA fingerprint
    description: |
    Returns a specific root certificate identified by its SHA fingerprint.
    This is useful when you know the specific root certificate you need.
    operationId: getRootBySHA
    parameters:
    - name: sha
    in: path
    required: true
    description: SHA fingerprint of the root certificate
    description: Template name for configuration
    schema:
    type: string
    example: "d9d020ce70ce5aab2e9fcae49c2a9f71c3b1e4a0"
    responses:
    '200':
    description: Root certificate retrieved successfully
    description: SSH configuration
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RootResponse'
    example:
    root: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    '404':
    $ref: '#/components/responses/NotFound'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/rekey:
    post:
    summary: Rekey a certificate
    description: |
    Generates a new certificate with a new public key while maintaining the same identity.
    This is useful for key rotation scenarios.
    operationId: rekeyCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RekeyRequest'
    example:
    csr: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    responses:
    '200':
    description: Certificate successfully rekeyed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/rekey:
    post:
    summary: Rekey SSH certificate
    description: Generates a new SSH certificate with a new public key
    operationId: rekeySSHCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRekeyRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    cert: "[email protected] AAAAHHNzaC1..."
    responses:
    '200':
    description: SSH certificate successfully rekeyed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'
    $ref: '#/components/schemas/SSHConfigResponse'

    /1.0/ssh/check-host:
    /ssh/check-host:
    post:
    summary: Check SSH host certificate
    description: Validates an SSH host certificate against the CA
    summary: Check SSH Host
    description: Check if an SSH host is valid and get host certificate
    operationId: checkSSHHost
    tags:
    - SSH Certificates
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHCheckHostRequest'
    example:
    hostname: "example.com"
    certificate: "[email protected] AAAAHHNzaC1..."
    responses:
    '200':
    description: SSH host certificate is valid
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHCheckHostResponse'
    example:
    valid: true
    principals: ["example.com", "*.example.com"]
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/bastion:
    post:
    summary: Get SSH bastion configuration
    description: Returns SSH bastion configuration for secure access
    operationId: getSSHBastion
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHBastionRequest'
    example:
    hostname: "bastion.example.com"
    user: "admin"
    responses:
    '200':
    description: SSH bastion configuration retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHBastionResponse'
    example:
    hostname: "bastion.example.com"
    user: "admin"
    port: 22
    command: "ssh -o UserKnownHostsFile=/dev/null..."
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/crl:
    get:
    summary: Get Certificate Revocation List
    description: |
    Returns the Certificate Revocation List (CRL) containing all revoked certificates.
    This is used by clients to check if a certificate has been revoked.
    operationId: getCRL
    type: object
    properties:
    host:
    type: string
    description: Hostname to check
    example: "example.com"
    port:
    type: string
    description: Port number
    default: "22"
    responses:
    '200':
    description: CRL retrieved successfully
    description: Host check result
    content:
    application/pkix-crl:
    schema:
    type: string
    format: binary
    description: DER-encoded Certificate Revocation List
    application/json:
    schema:
    $ref: '#/components/schemas/CRLResponse'
    example:
    crl: "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0t..."
    '500':
    $ref: '#/components/responses/InternalError'
    type: object
    properties:
    exists:
    type: boolean
    certificate:
    type: string
    description: SSH host certificate if available

    components:
    securitySchemes:
    BearerAuth:
    type: http
    scheme: bearer
    bearerFormat: JWT
    description: JWT token for authentication (One-Time Token)
    description: JWT token for authentication
    mTLS:
    type: mutualTLS
    description: Mutual TLS authentication using client certificates

    schemas:
    SignRequest:
    @@ -611,568 +415,331 @@ components:
    properties:
    csr:
    type: string
    description: Base64 encoded Certificate Signing Request (CSR)
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    description: PEM-encoded Certificate Signing Request
    example: |
    -----BEGIN CERTIFICATE REQUEST-----
    MIICWjCCAUICAQAwFTETMBEGA1UEAwwKZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
    ...
    -----END CERTIFICATE REQUEST-----
    ott:
    type: string
    description: One-Time Token (JWT) for authentication
    description: One-time token (JWT) for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    notAfter:
    provisioner:
    type: string
    format: date-time
    description: Certificate expiration time
    example: "2024-12-31T23:59:59Z"
    notBefore:
    type: string
    format: date-time
    description: Certificate valid from time
    example: "2024-01-01T00:00:00Z"
    description: Name of the provisioner to use
    example: "my-provisioner"

    SignResponse:
    type: object
    properties:
    cert:
    type: string
    description: Base64 encoded signed certificate
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    crt:
    type: string
    description: PEM-encoded signed certificate
    example: |
    -----BEGIN CERTIFICATE-----
    MIIBkTCB+wIJAK...
    -----END CERTIFICATE-----
    ca:
    type: string
    description: PEM-encoded CA certificate
    example: |
    -----BEGIN CERTIFICATE-----
    MIIBkTCB+wIJAK...
    -----END CERTIFICATE-----
    certChain:
    type: array
    items:
    type: string
    description: Certificate chain including intermediate certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    description: Full certificate chain

    RenewRequest:
    type: object
    required:
    - cert
    properties:
    cert:
    crt:
    type: string
    description: Base64 encoded certificate to renew
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    description: PEM-encoded certificate to renew
    example: |
    -----BEGIN CERTIFICATE-----
    MIIBkTCB+wIJAK...
    -----END CERTIFICATE-----

    RevokeRequest:
    type: object
    required:
    - serial
    properties:
    cert:
    type: string
    description: Base64 encoded certificate to revoke
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    serial:
    type: string
    description: Serial number of certificate to revoke (alternative to cert)
    description: Serial number of certificate to revoke
    example: "123456789"
    ott:
    crt:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    description: PEM-encoded certificate to revoke (alternative to serial)
    reason:
    type: string
    description: Reason for revocation
    enum:
    - unspecified
    - keyCompromise
    - cACompromise
    - caCompromise
    - affiliationChanged
    - superseded
    - cessationOfOperation
    - certificateHold
    - removeFromCRL
    - privilegeWithdrawn
    - aACompromise
    example: "cessationOfOperation"
    - aaCompromise
    default: unspecified
    reasonCode:
    type: integer
    description: Numeric reason code for revocation
    example: 5
    description: Numeric reason code
    minimum: 0
    maximum: 10
    passiveOnly:
    type: boolean
    description: Passive revocation only (don't add to CRL)
    default: false

    RevokeResponse:
    Provisioner:
    type: object
    properties:
    status:
    name:
    type: string
    description: Status of the revocation operation
    example: "ok"

    RootsResponse:
    type: object
    properties:
    roots:
    type: array
    items:
    type: string
    description: Array of Base64 encoded root certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]

    FederationResponse:
    type: object
    properties:
    federated:
    type: array
    items:
    type: string
    description: Array of Base64 encoded federated root certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]

    HealthResponse:
    type: object
    properties:
    status:
    description: Provisioner name
    example: "my-provisioner"
    type:
    type: string
    description: Health status of the server
    example: "ok"

    VersionResponse:
    type: object
    properties:
    version:
    description: Provisioner type
    enum: [JWK, OIDC, X5C, K8sSA, SSHPOP, ACME, SCEP, Nebula, AWS, Azure, GCP]
    example: "JWK"
    key:
    type: object
    description: Provisioner key configuration
    encryptedKey:
    type: string
    description: Version of the step-ca server
    example: "0.25.0"
    require_client_authentication:
    type: boolean
    description: Whether client authentication is required
    example: true
    description: Encrypted provisioner key
    claims:
    type: object
    description: Provisioner claims and constraints
    properties:
    minTLSCertDuration:
    type: string
    example: "1h"
    maxTLSCertDuration:
    type: string
    example: "8760h"
    defaultTLSCertDuration:
    type: string
    example: "24h"

    SSHSignRequest:
    type: object
    required:
    - ott
    - publicKey
    - certType
    - ott
    properties:
    publicKey:
    type: string
    description: SSH public key to sign
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey:
    description: One-time token for authentication
    validAfter:
    type: string
    description: SSH public key to be signed
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    description: Certificate valid after (RFC3339 format)
    validBefore:
    type: string
    description: Certificate valid before (RFC3339 format)
    certType:
    type: string
    enum: [user, host]
    description: Type of SSH certificate
    example: "user"
    default: user
    keyID:
    type: string
    description: Key identifier for the certificate
    example: "[email protected]"
    principals:
    type: array
    items:
    type: string
    description: List of principals (usernames/hostnames) for the certificate
    example: ["user", "admin"]
    validAfter:
    type: string
    format: date-time
    description: Certificate valid from time
    example: "2024-01-01T00:00:00Z"
    validBefore:
    type: string
    format: date-time
    description: Certificate valid until time
    example: "2024-12-31T23:59:59Z"
    description: List of principals (usernames/hostnames)

    SSHSignResponse:
    type: object
    properties:
    certificate:
    type: string
    description: Signed SSH certificate
    example: "[email protected] AAAAHHNzaC1..."
    identityID:
    type: string
    description: Identity ID of the certificate
    example: "[email protected]"

    SSHRenewRequest:
    type: object
    required:
    - ott
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."

    SSHRevokeRequest:
    type: object
    required:
    - ott
    - serial
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    serial:
    type: string
    description: Serial number of SSH certificate to revoke
    example: "1234567890"

    SSHRootsResponse:
    type: object
    properties:
    hostKey:
    type: string
    description: SSH CA public key for host certificates
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    userKey:
    type: string
    description: SSH CA public key for user certificates
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."

    SSHConfigRequest:
    type: object
    required:
    - type
    properties:
    type:
    type: string
    enum: [host, user]
    description: Type of SSH configuration
    example: "host"
    hostname:
    type: string
    description: Hostname for host configuration
    example: "example.com"

    SSHConfigResponse:
    type: object
    properties:
    config:
    type: string
    description: SSH client configuration
    example: "Host example.com\n HostKeyAlgorithms..."

    ProvisionersResponse:
    type: object
    properties:
    provisioners:
    description: SSH certificate
    example: "[email protected] AAAAB3NzaC1yc2..."
    identities:
    type: array
    items:
    $ref: '#/components/schemas/Provisioner'
    description: List of provisioners
    nextCursor:
    type: string
    description: Cursor for next page of results
    example: ""
    $ref: '#/components/schemas/SSHIdentity'

    Provisioner:
    SSHIdentity:
    type: object
    properties:
    id:
    type: string
    description: Unique identifier for the provisioner
    example: "acme"
    name:
    type: string
    description: Human-readable name of the provisioner
    example: "ACME"
    type:
    type: string
    enum: [JWK, OIDC, ACME, AWS, GCP, Azure, SCEP, Nebula, K8SSA]
    description: Type of provisioner
    example: "ACME"
    key:
    type: object
    description: Public key for JWK provisioners
    properties:
    kty:
    type: string
    example: "EC"
    crv:
    type: string
    example: "P-256"
    x:
    type: string
    example: "..."
    y:
    type: string
    example: "..."
    encryptedKey:
    type: string
    description: Encrypted private key (for some provisioner types)
    example: "..."
    clientID:
    type: string
    description: Client ID for OIDC provisioners
    example: "client-id"
    clientSecret:
    type: string
    description: Client secret for OIDC provisioners (usually not returned)
    example: "[REDACTED]"
    configurationEndpoint:
    type: string
    description: OIDC configuration endpoint
    example: "https://accounts.google.com/.well-known/openid_configuration"
    admins:
    type: array
    items:
    type: string
    description: List of admin emails for OIDC provisioners
    example: ["[email protected]"]
    domains:
    type: array
    items:
    type: string
    description: Allowed domains for OIDC provisioners
    example: ["example.com"]
    claims:
    $ref: '#/components/schemas/Claims'
    options:
    type: object
    description: Additional provisioner-specific options
    additionalProperties: true

    Claims:
    type: object
    description: Certificate claims and constraints
    properties:
    minTLSCertDuration:
    type: string
    description: Minimum TLS certificate duration
    example: "5m"
    maxTLSCertDuration:
    type: string
    description: Maximum TLS certificate duration
    example: "24h"
    defaultTLSCertDuration:
    type: string
    description: Default TLS certificate duration
    example: "24h"
    minUserSSHCertDuration:
    type: string
    description: Minimum SSH user certificate duration
    example: "5m"
    maxUserSSHCertDuration:
    type: string
    description: Maximum SSH user certificate duration
    example: "24h"
    defaultUserSSHCertDuration:
    type: string
    description: Default SSH user certificate duration
    example: "16h"
    minHostSSHCertDuration:
    type: string
    description: Minimum SSH host certificate duration
    example: "5m"
    maxHostSSHCertDuration:
    type: string
    description: Maximum SSH host certificate duration
    example: "720h"
    defaultHostSSHCertDuration:
    type: string
    description: Default SSH host certificate duration
    example: "720h"
    enableSSHCA:
    type: boolean
    description: Whether SSH CA is enabled
    example: true
    disableRenewal:
    type: boolean
    description: Whether certificate renewal is disabled
    example: false
    allowRenewalAfterExpiry:
    type: boolean
    description: Whether renewal is allowed after certificate expiry
    example: false

    RootResponse:
    type: object
    properties:
    root:
    type: string
    description: Base64 encoded root certificate
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."

    RekeyRequest:
    type: object
    required:
    - csr
    - cert
    properties:
    csr:
    type: string
    description: Base64 encoded Certificate Signing Request with new public key
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    cert:
    type: string
    description: Base64 encoded current certificate to be rekeyed
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."

    SSHRekeyRequest:
    type: object
    required:
    - ott
    - publicKey
    - cert
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey:
    enum: [user, host]
    certificate:
    type: string
    description: New SSH public key
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    cert:
    description: SSH certificate
    config:
    type: string
    description: Current SSH certificate to be rekeyed
    example: "[email protected] AAAAHHNzaC1..."
    description: SSH configuration snippet

    SSHCheckHostRequest:
    SSHRenewRequest:
    type: object
    required:
    - hostname
    - certificate
    properties:
    hostname:
    type: string
    description: Hostname to validate against
    example: "example.com"
    certificate:
    type: string
    description: SSH host certificate to validate
    example: "[email protected] AAAAHHNzaC1..."

    SSHCheckHostResponse:
    type: object
    properties:
    valid:
    type: boolean
    description: Whether the certificate is valid for the hostname
    example: true
    principals:
    type: array
    items:
    type: string
    description: Valid principals from the certificate
    example: ["example.com", "*.example.com"]
    description: SSH certificate to renew

    SSHBastionRequest:
    SSHRevokeRequest:
    type: object
    required:
    - hostname
    properties:
    hostname:
    type: string
    description: Bastion hostname
    example: "bastion.example.com"
    user:
    type: string
    description: SSH user
    example: "admin"

    SSHBastionResponse:
    type: object
    - serial
    properties:
    hostname:
    type: string
    description: Bastion hostname
    example: "bastion.example.com"
    user:
    type: string
    description: SSH user
    example: "admin"
    port:
    type: integer
    description: SSH port
    example: 22
    command:
    serial:
    type: string
    description: SSH command to connect through bastion
    example: "ssh -o UserKnownHostsFile=/dev/null..."
    description: Serial number of SSH certificate to revoke

    CRLResponse:
    SSHConfigResponse:
    type: object
    properties:
    crl:
    config:
    type: string
    description: Base64 encoded Certificate Revocation List
    example: "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0t..."
    description: SSH configuration content
    example: |
    Host *
    UserKnownHostsFile ~/.ssh/known_hosts ~/.ssh/known_hosts_ca
    CertificateFile ~/.ssh/id_ecdsa-cert.pub

    Error:
    type: object
    properties:
    status:
    type: integer
    description: HTTP status code
    example: 400
    message:
    type: string
    description: Error message
    example: "Bad request"
    detail:
    details:
    type: string
    description: Detailed error information
    example: "Invalid certificate signing request format"
    description: Additional error details

    responses:
    BadRequest:
    description: Bad request - invalid input parameters
    description: Bad Request
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 400
    message: "Bad request"
    detail: "Invalid certificate signing request format"

    message: "Invalid request format"

    Unauthorized:
    description: Unauthorized - invalid or missing authentication
    description: Unauthorized
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 401
    message: "Unauthorized"
    detail: "Invalid or expired JWT token"

    message: "Authentication required"

    Forbidden:
    description: Forbidden - insufficient permissions
    description: Forbidden
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 403
    message: "Forbidden"
    detail: "Insufficient permissions for this operation"

    message: "Access denied"

    NotFound:
    description: Resource not found
    description: Not Found
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 404
    message: "Not found"
    detail: "The requested resource was not found"

    InternalError:
    description: Internal server error
    message: "Resource not found"

    InternalServerError:
    description: Internal Server Error
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 500
    message: "Internal server error"
    detail: "Failed to process certificate request"

    tags:
    - name: Health
    description: Health check operations
    - name: Certificates
    description: X.509 certificate operations
    - name: SSH
    - name: SSH Certificates
    description: SSH certificate operations
    - name: CA Management
    description: Certificate Authority management endpoints
    - name: System
    description: System health and information endpoints
    - name: Provisioners
    description: Provisioner management operations

    externalDocs:
    description: Smallstep Certificates Documentation
    url: https://smallstep.com/docs/step-ca/
    ```

    ## Usage Examples

    ### Basic Certificate Signing
    ```bash
    # Get a one-time token
    step ca token example.com

    # Sign a certificate
    curl -X POST https://ca.example.com:9000/1.0/sign \
    -H "Content-Type: application/json" \
    -d '{
    "csr": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----",
    "ott": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    }'
    ```

    ### Health Check
    ```bash
    curl https://ca.example.com:9000/1.0/health
    ```

    ### Get Root Certificate
    ```bash
    curl https://ca.example.com:9000/1.0/roots
    ```

    ### SSH Certificate Signing
    ```bash
    curl -X POST https://ca.example.com:9000/1.0/ssh/sign \
    -H "Content-Type: application/json" \
    -d '{
    "publicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...",
    "ott": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
    "certType": "user",
    "principals": ["alice", "bob"]
    }'
    ```

    ## Notes

    This Swagger documentation is based on the smallstep/certificates API structure. The actual implementation may have additional endpoints or slight variations. For the most up-to-date information, refer to:

    - [Smallstep Certificates GitHub Repository](https://github.com/smallstep/certificates)
    - [Official Documentation](https://smallstep.com/docs/step-ca/)
    - [API Client Examples](https://github.com/smallstep/clients)
  4. mcarbonneaux revised this gist May 29, 2025. No changes.
  5. mcarbonneaux revised this gist May 29, 2025. No changes.
  6. mcarbonneaux revised this gist May 29, 2025. 1 changed file with 507 additions and 0 deletions.
    507 changes: 507 additions & 0 deletions smallstep-api.swagger
    Original file line number Diff line number Diff line change
    @@ -345,6 +345,255 @@ paths:
    '500':
    $ref: '#/components/responses/InternalError'

    /provisioners:
    get:
    summary: Get all provisioners
    description: |
    Returns a list of all configured provisioners on the CA.
    This endpoint is typically used to discover available provisioners and their capabilities.
    operationId: getProvisioners
    parameters:
    - name: cursor
    in: query
    description: Cursor for pagination
    required: false
    schema:
    type: string
    - name: limit
    in: query
    description: Maximum number of provisioners to return
    required: false
    schema:
    type: integer
    default: 20
    maximum: 100
    responses:
    '200':
    description: Provisioners retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/ProvisionersResponse'
    example:
    provisioners:
    - id: "acme"
    name: "ACME"
    type: "ACME"
    encryptedKey: ""
    claims:
    minTLSCertDuration: "5m"
    maxTLSCertDuration: "24h"
    defaultTLSCertDuration: "24h"
    - id: "jwk-provisioner"
    name: "JWK"
    type: "JWK"
    key:
    kty: "EC"
    crv: "P-256"
    x: "..."
    y: "..."
    encryptedKey: "..."
    nextCursor: ""
    '500':
    $ref: '#/components/responses/InternalError'

    /provisioners/{provisionerID}:
    get:
    summary: Get provisioner by ID
    description: Returns detailed information about a specific provisioner
    operationId: getProvisionerByID
    parameters:
    - name: provisionerID
    in: path
    required: true
    description: ID of the provisioner
    schema:
    type: string
    example: "acme"
    responses:
    '200':
    description: Provisioner retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Provisioner'
    '404':
    $ref: '#/components/responses/NotFound'
    '500':
    $ref: '#/components/responses/InternalError'

    /root/{sha}:
    get:
    summary: Get root certificate by SHA fingerprint
    description: |
    Returns a specific root certificate identified by its SHA fingerprint.
    This is useful when you know the specific root certificate you need.
    operationId: getRootBySHA
    parameters:
    - name: sha
    in: path
    required: true
    description: SHA fingerprint of the root certificate
    schema:
    type: string
    example: "d9d020ce70ce5aab2e9fcae49c2a9f71c3b1e4a0"
    responses:
    '200':
    description: Root certificate retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RootResponse'
    example:
    root: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    '404':
    $ref: '#/components/responses/NotFound'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/rekey:
    post:
    summary: Rekey a certificate
    description: |
    Generates a new certificate with a new public key while maintaining the same identity.
    This is useful for key rotation scenarios.
    operationId: rekeyCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RekeyRequest'
    example:
    csr: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    responses:
    '200':
    description: Certificate successfully rekeyed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/rekey:
    post:
    summary: Rekey SSH certificate
    description: Generates a new SSH certificate with a new public key
    operationId: rekeySSHCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRekeyRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    cert: "[email protected] AAAAHHNzaC1..."
    responses:
    '200':
    description: SSH certificate successfully rekeyed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/check-host:
    post:
    summary: Check SSH host certificate
    description: Validates an SSH host certificate against the CA
    operationId: checkSSHHost
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHCheckHostRequest'
    example:
    hostname: "example.com"
    certificate: "[email protected] AAAAHHNzaC1..."
    responses:
    '200':
    description: SSH host certificate is valid
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHCheckHostResponse'
    example:
    valid: true
    principals: ["example.com", "*.example.com"]
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/bastion:
    post:
    summary: Get SSH bastion configuration
    description: Returns SSH bastion configuration for secure access
    operationId: getSSHBastion
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHBastionRequest'
    example:
    hostname: "bastion.example.com"
    user: "admin"
    responses:
    '200':
    description: SSH bastion configuration retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHBastionResponse'
    example:
    hostname: "bastion.example.com"
    user: "admin"
    port: 22
    command: "ssh -o UserKnownHostsFile=/dev/null..."
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/crl:
    get:
    summary: Get Certificate Revocation List
    description: |
    Returns the Certificate Revocation List (CRL) containing all revoked certificates.
    This is used by clients to check if a certificate has been revoked.
    operationId: getCRL
    responses:
    '200':
    description: CRL retrieved successfully
    content:
    application/pkix-crl:
    schema:
    type: string
    format: binary
    description: DER-encoded Certificate Revocation List
    application/json:
    schema:
    $ref: '#/components/schemas/CRLResponse'
    example:
    crl: "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0t..."
    '500':
    $ref: '#/components/responses/InternalError'

    components:
    securitySchemes:
    BearerAuth:
    @@ -599,6 +848,253 @@ components:
    description: SSH client configuration
    example: "Host example.com\n HostKeyAlgorithms..."

    ProvisionersResponse:
    type: object
    properties:
    provisioners:
    type: array
    items:
    $ref: '#/components/schemas/Provisioner'
    description: List of provisioners
    nextCursor:
    type: string
    description: Cursor for next page of results
    example: ""

    Provisioner:
    type: object
    properties:
    id:
    type: string
    description: Unique identifier for the provisioner
    example: "acme"
    name:
    type: string
    description: Human-readable name of the provisioner
    example: "ACME"
    type:
    type: string
    enum: [JWK, OIDC, ACME, AWS, GCP, Azure, SCEP, Nebula, K8SSA]
    description: Type of provisioner
    example: "ACME"
    key:
    type: object
    description: Public key for JWK provisioners
    properties:
    kty:
    type: string
    example: "EC"
    crv:
    type: string
    example: "P-256"
    x:
    type: string
    example: "..."
    y:
    type: string
    example: "..."
    encryptedKey:
    type: string
    description: Encrypted private key (for some provisioner types)
    example: "..."
    clientID:
    type: string
    description: Client ID for OIDC provisioners
    example: "client-id"
    clientSecret:
    type: string
    description: Client secret for OIDC provisioners (usually not returned)
    example: "[REDACTED]"
    configurationEndpoint:
    type: string
    description: OIDC configuration endpoint
    example: "https://accounts.google.com/.well-known/openid_configuration"
    admins:
    type: array
    items:
    type: string
    description: List of admin emails for OIDC provisioners
    example: ["[email protected]"]
    domains:
    type: array
    items:
    type: string
    description: Allowed domains for OIDC provisioners
    example: ["example.com"]
    claims:
    $ref: '#/components/schemas/Claims'
    options:
    type: object
    description: Additional provisioner-specific options
    additionalProperties: true

    Claims:
    type: object
    description: Certificate claims and constraints
    properties:
    minTLSCertDuration:
    type: string
    description: Minimum TLS certificate duration
    example: "5m"
    maxTLSCertDuration:
    type: string
    description: Maximum TLS certificate duration
    example: "24h"
    defaultTLSCertDuration:
    type: string
    description: Default TLS certificate duration
    example: "24h"
    minUserSSHCertDuration:
    type: string
    description: Minimum SSH user certificate duration
    example: "5m"
    maxUserSSHCertDuration:
    type: string
    description: Maximum SSH user certificate duration
    example: "24h"
    defaultUserSSHCertDuration:
    type: string
    description: Default SSH user certificate duration
    example: "16h"
    minHostSSHCertDuration:
    type: string
    description: Minimum SSH host certificate duration
    example: "5m"
    maxHostSSHCertDuration:
    type: string
    description: Maximum SSH host certificate duration
    example: "720h"
    defaultHostSSHCertDuration:
    type: string
    description: Default SSH host certificate duration
    example: "720h"
    enableSSHCA:
    type: boolean
    description: Whether SSH CA is enabled
    example: true
    disableRenewal:
    type: boolean
    description: Whether certificate renewal is disabled
    example: false
    allowRenewalAfterExpiry:
    type: boolean
    description: Whether renewal is allowed after certificate expiry
    example: false

    RootResponse:
    type: object
    properties:
    root:
    type: string
    description: Base64 encoded root certificate
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."

    RekeyRequest:
    type: object
    required:
    - csr
    - cert
    properties:
    csr:
    type: string
    description: Base64 encoded Certificate Signing Request with new public key
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    cert:
    type: string
    description: Base64 encoded current certificate to be rekeyed
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."

    SSHRekeyRequest:
    type: object
    required:
    - ott
    - publicKey
    - cert
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey:
    type: string
    description: New SSH public key
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    cert:
    type: string
    description: Current SSH certificate to be rekeyed
    example: "[email protected] AAAAHHNzaC1..."

    SSHCheckHostRequest:
    type: object
    required:
    - hostname
    - certificate
    properties:
    hostname:
    type: string
    description: Hostname to validate against
    example: "example.com"
    certificate:
    type: string
    description: SSH host certificate to validate
    example: "[email protected] AAAAHHNzaC1..."

    SSHCheckHostResponse:
    type: object
    properties:
    valid:
    type: boolean
    description: Whether the certificate is valid for the hostname
    example: true
    principals:
    type: array
    items:
    type: string
    description: Valid principals from the certificate
    example: ["example.com", "*.example.com"]

    SSHBastionRequest:
    type: object
    required:
    - hostname
    properties:
    hostname:
    type: string
    description: Bastion hostname
    example: "bastion.example.com"
    user:
    type: string
    description: SSH user
    example: "admin"

    SSHBastionResponse:
    type: object
    properties:
    hostname:
    type: string
    description: Bastion hostname
    example: "bastion.example.com"
    user:
    type: string
    description: SSH user
    example: "admin"
    port:
    type: integer
    description: SSH port
    example: 22
    command:
    type: string
    description: SSH command to connect through bastion
    example: "ssh -o UserKnownHostsFile=/dev/null..."

    CRLResponse:
    type: object
    properties:
    crl:
    type: string
    description: Base64 encoded Certificate Revocation List
    example: "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0t..."

    Error:
    type: object
    properties:
    @@ -649,6 +1145,17 @@ components:
    message: "Forbidden"
    detail: "Insufficient permissions for this operation"

    NotFound:
    description: Resource not found
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 404
    message: "Not found"
    detail: "The requested resource was not found"

    InternalError:
    description: Internal server error
    content:
  7. mcarbonneaux created this gist May 29, 2025.
    671 changes: 671 additions & 0 deletions smallstep-api.swagger
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,671 @@
    openapi: 3.0.3
    info:
    title: Smallstep Certificates API
    description: |
    REST API for Smallstep Certificates - A private certificate authority (X.509 & SSH) & ACME server
    for secure automated certificate management.

    This API allows you to:
    - Sign certificate requests
    - Revoke certificates
    - Renew certificates
    - Get CA roots and federation
    - Manage SSH certificates

    Authentication is typically done using JWT tokens or provisioner-specific authentication methods.
    version: 1.0.0
    contact:
    name: Smallstep
    url: https://github.com/smallstep/certificates
    license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0

    servers:
    - url: https://localhost:9000
    description: Default step-ca server
    - url: https://ca.example.com
    description: Production CA server

    security:
    - BearerAuth: []

    paths:
    /1.0/sign:
    post:
    summary: Sign a certificate signing request
    description: |
    Signs a Certificate Signing Request (CSR) and returns a signed certificate.
    Requires proper authentication via JWT token or other provisioner methods.
    operationId: signCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignRequest'
    example:
    csr: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    notAfter: "2024-12-31T23:59:59Z"
    notBefore: "2024-01-01T00:00:00Z"
    responses:
    '200':
    description: Certificate successfully signed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignResponse'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    certChain: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/renew:
    post:
    summary: Renew a certificate
    description: |
    Renews an existing certificate. The request must include the current certificate
    and proper authentication.
    operationId: renewCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RenewRequest'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    responses:
    '200':
    description: Certificate successfully renewed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/revoke:
    post:
    summary: Revoke a certificate
    description: |
    Revokes a certificate using either the certificate itself or its serial number.
    Requires proper authentication and authorization.
    operationId: revokeCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeRequest'
    example:
    cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    reason: "cessationOfOperation"
    reasonCode: 5
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    responses:
    '200':
    description: Certificate successfully revoked
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeResponse'
    example:
    status: "ok"
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/roots:
    get:
    summary: Get CA root certificates
    description: |
    Returns the root certificates of the Certificate Authority.
    This endpoint is typically public and doesn't require authentication.
    operationId: getRoots
    responses:
    '200':
    description: Root certificates retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RootsResponse'
    example:
    roots: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/federation:
    get:
    summary: Get federation certificates
    description: |
    Returns the federated root certificates that this CA trusts.
    Used for cross-CA certificate validation.
    operationId: getFederation
    responses:
    '200':
    description: Federation certificates retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/FederationResponse'
    example:
    federated: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/health:
    get:
    summary: Health check
    description: Returns the health status of the CA server
    operationId: getHealth
    responses:
    '200':
    description: Server is healthy
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/HealthResponse'
    example:
    status: "ok"
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/version:
    get:
    summary: Get version information
    description: Returns version information about the CA server
    operationId: getVersion
    responses:
    '200':
    description: Version information retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/VersionResponse'
    example:
    version: "0.25.0"
    require_client_authentication: true

    /1.0/ssh/sign:
    post:
    summary: Sign SSH certificate
    description: |
    Signs an SSH certificate request and returns a signed SSH certificate.
    Used for SSH certificate-based authentication.
    operationId: signSSHCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    certType: "user"
    keyID: "[email protected]"
    principals: ["user", "admin"]
    validAfter: "2024-01-01T00:00:00Z"
    validBefore: "2024-12-31T23:59:59Z"
    responses:
    '200':
    description: SSH certificate successfully signed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignResponse'
    example:
    certificate: "[email protected] AAAAHHNzaC1..."
    identityID: "[email protected]"
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '403':
    $ref: '#/components/responses/Forbidden'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/renew:
    post:
    summary: Renew SSH certificate
    description: Renews an existing SSH certificate
    operationId: renewSSHCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRenewRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    responses:
    '200':
    description: SSH certificate successfully renewed
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHSignResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/revoke:
    post:
    summary: Revoke SSH certificate
    description: Revokes an SSH certificate
    operationId: revokeSSHCertificate
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRevokeRequest'
    example:
    ott: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    serial: "1234567890"
    responses:
    '200':
    description: SSH certificate successfully revoked
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/RevokeResponse'
    '400':
    $ref: '#/components/responses/BadRequest'
    '401':
    $ref: '#/components/responses/Unauthorized'
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/roots:
    get:
    summary: Get SSH CA public keys
    description: Returns the SSH CA public keys for host and user certificates
    operationId: getSSHRoots
    responses:
    '200':
    description: SSH roots retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHRootsResponse'
    example:
    hostKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    userKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    '500':
    $ref: '#/components/responses/InternalError'

    /1.0/ssh/config:
    post:
    summary: Get SSH client configuration
    description: Returns SSH client configuration for the given host
    operationId: getSSHConfig
    requestBody:
    required: true
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHConfigRequest'
    example:
    type: "host"
    hostname: "example.com"
    responses:
    '200':
    description: SSH configuration retrieved successfully
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/SSHConfigResponse'
    example:
    config: "Host example.com\n HostKeyAlgorithms..."
    '400':
    $ref: '#/components/responses/BadRequest'
    '500':
    $ref: '#/components/responses/InternalError'

    components:
    securitySchemes:
    BearerAuth:
    type: http
    scheme: bearer
    bearerFormat: JWT
    description: JWT token for authentication (One-Time Token)

    schemas:
    SignRequest:
    type: object
    required:
    - csr
    - ott
    properties:
    csr:
    type: string
    description: Base64 encoded Certificate Signing Request (CSR)
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..."
    ott:
    type: string
    description: One-Time Token (JWT) for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    notAfter:
    type: string
    format: date-time
    description: Certificate expiration time
    example: "2024-12-31T23:59:59Z"
    notBefore:
    type: string
    format: date-time
    description: Certificate valid from time
    example: "2024-01-01T00:00:00Z"

    SignResponse:
    type: object
    properties:
    cert:
    type: string
    description: Base64 encoded signed certificate
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    certChain:
    type: array
    items:
    type: string
    description: Certificate chain including intermediate certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]

    RenewRequest:
    type: object
    required:
    - cert
    properties:
    cert:
    type: string
    description: Base64 encoded certificate to renew
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."

    RevokeRequest:
    type: object
    properties:
    cert:
    type: string
    description: Base64 encoded certificate to revoke
    example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    serial:
    type: string
    description: Serial number of certificate to revoke (alternative to cert)
    example: "123456789"
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    reason:
    type: string
    description: Reason for revocation
    enum:
    - unspecified
    - keyCompromise
    - cACompromise
    - affiliationChanged
    - superseded
    - cessationOfOperation
    - certificateHold
    - removeFromCRL
    - privilegeWithdrawn
    - aACompromise
    example: "cessationOfOperation"
    reasonCode:
    type: integer
    description: Numeric reason code for revocation
    example: 5

    RevokeResponse:
    type: object
    properties:
    status:
    type: string
    description: Status of the revocation operation
    example: "ok"

    RootsResponse:
    type: object
    properties:
    roots:
    type: array
    items:
    type: string
    description: Array of Base64 encoded root certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]

    FederationResponse:
    type: object
    properties:
    federated:
    type: array
    items:
    type: string
    description: Array of Base64 encoded federated root certificates
    example: ["LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."]

    HealthResponse:
    type: object
    properties:
    status:
    type: string
    description: Health status of the server
    example: "ok"

    VersionResponse:
    type: object
    properties:
    version:
    type: string
    description: Version of the step-ca server
    example: "0.25.0"
    require_client_authentication:
    type: boolean
    description: Whether client authentication is required
    example: true

    SSHSignRequest:
    type: object
    required:
    - ott
    - publicKey
    - certType
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    publicKey:
    type: string
    description: SSH public key to be signed
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    certType:
    type: string
    enum: [user, host]
    description: Type of SSH certificate
    example: "user"
    keyID:
    type: string
    description: Key identifier for the certificate
    example: "[email protected]"
    principals:
    type: array
    items:
    type: string
    description: List of principals (usernames/hostnames) for the certificate
    example: ["user", "admin"]
    validAfter:
    type: string
    format: date-time
    description: Certificate valid from time
    example: "2024-01-01T00:00:00Z"
    validBefore:
    type: string
    format: date-time
    description: Certificate valid until time
    example: "2024-12-31T23:59:59Z"

    SSHSignResponse:
    type: object
    properties:
    certificate:
    type: string
    description: Signed SSH certificate
    example: "[email protected] AAAAHHNzaC1..."
    identityID:
    type: string
    description: Identity ID of the certificate
    example: "[email protected]"

    SSHRenewRequest:
    type: object
    required:
    - ott
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."

    SSHRevokeRequest:
    type: object
    required:
    - ott
    - serial
    properties:
    ott:
    type: string
    description: One-Time Token for authentication
    example: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    serial:
    type: string
    description: Serial number of SSH certificate to revoke
    example: "1234567890"

    SSHRootsResponse:
    type: object
    properties:
    hostKey:
    type: string
    description: SSH CA public key for host certificates
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."
    userKey:
    type: string
    description: SSH CA public key for user certificates
    example: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."

    SSHConfigRequest:
    type: object
    required:
    - type
    properties:
    type:
    type: string
    enum: [host, user]
    description: Type of SSH configuration
    example: "host"
    hostname:
    type: string
    description: Hostname for host configuration
    example: "example.com"

    SSHConfigResponse:
    type: object
    properties:
    config:
    type: string
    description: SSH client configuration
    example: "Host example.com\n HostKeyAlgorithms..."

    Error:
    type: object
    properties:
    status:
    type: integer
    description: HTTP status code
    example: 400
    message:
    type: string
    description: Error message
    example: "Bad request"
    detail:
    type: string
    description: Detailed error information
    example: "Invalid certificate signing request format"

    responses:
    BadRequest:
    description: Bad request - invalid input parameters
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 400
    message: "Bad request"
    detail: "Invalid certificate signing request format"

    Unauthorized:
    description: Unauthorized - invalid or missing authentication
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 401
    message: "Unauthorized"
    detail: "Invalid or expired JWT token"

    Forbidden:
    description: Forbidden - insufficient permissions
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 403
    message: "Forbidden"
    detail: "Insufficient permissions for this operation"

    InternalError:
    description: Internal server error
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Error'
    example:
    status: 500
    message: "Internal server error"
    detail: "Failed to process certificate request"

    tags:
    - name: Certificates
    description: X.509 certificate operations
    - name: SSH
    description: SSH certificate operations
    - name: CA Management
    description: Certificate Authority management endpoints
    - name: System
    description: System health and information endpoints