> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# List personal SSH keys

> Requires the signed-in human user. Personal keys apply to that user across organization memberships; the organization selects only the Linux identity. A key never carries a role or grants access to a VM by itself. Linux names and numeric IDs are allocated by the platform and do not change on key rotation or display-name changes.

<Info>
  Requires **no IAM action**. Access is decided by the endpoint's own
  rules rather than by a policy — see the description above.
</Info>


## OpenAPI

````yaml /api-reference/specs/iam.yaml get /v1/auth/ssh-keys
openapi: 3.0.3
info:
  title: Basaltic IAM API
  version: 1.0.0
  description: >
    Account identity and access management: service accounts, roles, account
    policies, and account-scoped temporary sessions. Authentication and personal
    sign-in remain in IAM. Organizations, accounts, users, groups, and
    organization policies are managed by the Workspace API.


    Roles and custom policies belong to the selected account. Their global CRNs
    use an empty region and the owning account handle. Shared system policies
    use crn:iam:::policy/<name>. Relationship inputs are classified once as CRN,
    UUID, or name, without syntax fallback.


    AssumeRole resolves the target role's owning account. The caller needs
    source permission and the target role must trust the caller; the resulting
    session uses only the target role's permissions, subject to boundaries and
    session restrictions.
  contact:
    name: Basaltic Support
    email: ping@basaltic.sh
  license:
    name: Proprietary
    url: https://basaltic.sh/terms
servers:
  - url: https://iam.basaltic.sh
    description: Global API endpoint
security:
  - BearerAuth: []
paths:
  /v1/auth/ssh-keys:
    get:
      tags:
        - SSH Credentials
      summary: List personal SSH keys
      description: >-
        Requires the signed-in human user. Personal keys apply to that user
        across organization memberships; the organization selects only the Linux
        identity. A key never carries a role or grants access to a VM by itself.
        Linux names and numeric IDs are allocated by the platform and do not
        change on key rotation or display-name changes.
      operationId: listPersonalSSHKeys
      responses:
        '200':
          description: SSH credentials
          content:
            application/json:
              schema:
                type: object
                required:
                  - ssh_keys
                properties:
                  ssh_keys:
                    type: array
                    maxItems: 50
                    items:
                      $ref: '#/components/schemas/SSHKey'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
components:
  schemas:
    SSHKey:
      type: object
      required:
        - id
        - crn
        - name
        - public_key
        - fingerprint
        - algorithm
        - created_at
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        crn:
          type: string
          readOnly: true
          description: Identity-owned SSH credential CRN.
        name:
          type: string
          maxLength: 128
        public_key:
          type: string
          description: >-
            Canonical OpenSSH public key without a comment or authorized_keys
            options.
        fingerprint:
          type: string
          readOnly: true
          description: SHA-256 fingerprint in OpenSSH format.
        algorithm:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        expires_at:
          type: string
          format: date-time
          description: Optional expiry. Expired keys remain listed until revoked.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: Error code identifying the type of error
              example: INVALID_INPUT
            message:
              type: string
              description: Human-readable error message
              example: Invalid request parameters
            request_id:
              type: string
              format: uuid
              description: Request ID for debugging
              example: 550e8400-e29b-41d4-a716-446655440000
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_INPUT
              message: Invalid request parameters
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Unauthorized:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UNAUTHORIZED
              message: Authentication required
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ACCESS_DENIED
              message: You don't have permission to perform this action
              request_id: 550e8400-e29b-41d4-a716-446655440000
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: NOT_FOUND
              message: Resource not found
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Conflict:
      description: Resource conflict (e.g., already exists, invalid state)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: CONFLICT
              message: Resource with this name already exists
              request_id: 550e8400-e29b-41d4-a716-446655440000
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INTERNAL_ERROR
              message: An internal error occurred
              request_id: 550e8400-e29b-41d4-a716-446655440000
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        An OAuth 2.0 bearer token, sent as `Authorization: Bearer <token>`.
        This is the recommended way to authenticate.

        Get one by exchanging a service account's access key pair at
        `POST /v1/oauth/token` with `grant_type=client_credentials`. It is the
        standard client-credentials grant, so any OAuth-aware library will
        obtain and refresh it for you.

        ```
        curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
          https://iam.basaltic.sh/v1/oauth/token
        ```

        Tokens last an hour by default. The same access key pair is separately
        your AWS SigV4 credential for the S3-compatible object endpoint, which
        speaks nothing else.

````