openapi: 3.1.0 info: title: Keystack Auth API version: 0.1.0 servers: - url: / paths: /api/keys: get: operationId: getJwks summary: Get JSON Web Key Set tags: [keys] responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/JwkSet" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/keys/algorithms: get: operationId: getKeyAlgorithms summary: Get supported key algorithms tags: [keys] security: - bearerAuth: [] - oauth: [] responses: 200: description: Success content: application/json: schema: type: array items: { type: string } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/keys/metadata: get: operationId: getAllKeysMetadata summary: Get all keys metadata tags: [keys] security: - bearerAuth: [] - oauth: [] responses: 200: description: Success content: application/json: schema: type: array items: { $ref: "#/components/schemas/KeyMetadata" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/key: post: operationId: generateKey summary: Generate new key using provided algorithm tags: [keys] security: - bearerAuth: [] - oauth: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/KeyGenerationReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/KeyMetadata" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/key/{uuid}: delete: operationId: revokeKey summary: Revoke existing key tags: [keys] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 204: description: Success 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/auth: post: operationId: authWithPassword summary: Authenticate a user with email and password tags: [users] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/AuthWithPasswordReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/AuthResp" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 403: description: Forbidden content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/me: get: operationId: getMyDetails summary: Get authenticated user details tags: [users] security: - bearerAuth: [] - oauth: [] responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/logout/everywhere: post: operationId: logoutEverywhere summary: Logout from all devices tags: [users] security: - bearerAuth: [] - oauth: [] responses: 204: description: Success 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/me/password: put: operationId: setMyPassword summary: Update the authenticated user's password tags: [users] security: - bearerAuth: [] - oauth: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/SetMyPasswordReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/users: get: operationId: getAllUsers summary: Get list of all users tags: [users] security: - bearerAuth: [] - oauth: [] responses: 200: description: Success content: application/json: schema: type: array items: { $ref: "#/components/schemas/User" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user: post: operationId: createUser summary: Create new user tags: [users] security: - bearerAuth: [] - oauth: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/UserCreateReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 409: description: Conflict content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/{uuid}: get: operationId: getUserDetails summary: Get user details by uuid tags: [users] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 403: description: Forbidden content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } put: operationId: updateUser summary: Update user by uuid tags: [users] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/UserUpdateReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 409: description: Conflict content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } delete: operationId: deleteUser summary: Delete user by uuid tags: [users] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 204: description: Success 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 403: description: Forbidden content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/user/{uuid}/password: put: operationId: setUserPassword summary: Set user password by uuid tags: [users] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/SetUserPasswordReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/UserDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 403: description: Forbidden content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth-clients: get: operationId: getAllOAuthClients summary: Get list of all OAuth clients tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] responses: 200: description: Success content: application/json: schema: type: array items: { $ref: "#/components/schemas/OAuthClient" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth-client: post: operationId: createOAuthClient summary: Create OAuth client tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/OAuthClientCreateReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthClientDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 409: description: Conflict content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth-client/{uuid}: get: operationId: getOAuthClientDetails summary: Get OAuth client details by uuid tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthClientDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } put: operationId: updateOAuthClient summary: Update OAuth client by uuid tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/OAuthClientUpdateReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthClientDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 409: description: Conflict content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } delete: operationId: deleteOAuthClient summary: Delete OAuth client by uuid tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 204: description: Success 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth-client/{uuid}/primary-secret: post: operationId: rotateOAuthClientPrimarySecret summary: Regenerate primary secret for OAuth client tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthClientDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth-client/{uuid}/secondary-secret: delete: operationId: purgeOAuthClientSecondarySecret summary: Purge OAuth client secondary secret tags: [oauth-clients] security: - bearerAuth: [] - oauth: [] parameters: - name: uuid in: path required: true schema: { type: string } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthClientDetails" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth: post: operationId: oauth tags: [oauth] security: - bearerAuth: [] - oauth: [] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/OAuthReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthResp" } 400: description: Bad request content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } /api/oauth/token: post: operationId: oauthToken tags: [oauth] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/OAuthTokenReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthTokenResp" } 400: description: Bad request content: application/json: schema: { $ref: "#/components/schemas/OAuthErrorResp" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/OAuthErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/OAuthErrorResp" } /api/oauth/token_info: post: operationId: getOAuthTokenInfo tags: [oauth] security: - oauthClient: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: { $ref: "#/components/schemas/OAuthTokenInfoReq" } responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthTokenInfoResp" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/OAuthErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/OAuthErrorResp" } /api/oauth/userinfo: get: operationId: getOAuthUserInfo tags: [oauth] security: - oauth: [] responses: 200: description: Success content: application/json: schema: { $ref: "#/components/schemas/OAuthUserInfo" } 401: description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 404: description: Not found content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } 500: description: Internal server error content: application/json: schema: { $ref: "#/components/schemas/ErrorResp" } components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT oauth: type: oauth2 flows: authorizationCode: authorizationUrl: /authorize tokenUrl: /api/oauth/token scopes: {} oauthClient: type: http scheme: basic schemas: ErrorResp: type: object properties: status_code: { type: integer } status: { type: string } error: { type: string } required: [ status_code, status, error ] JwkSet: type: object properties: keys: type: array items: $ref: "#/components/schemas/Jwk" required: [ keys ] Jwk: type: object properties: kid: { type: string } kty: { type: string } alg: { type: string } use: { type: string } n: { type: string } e: { type: string } required: [ kid, kty, alg, use, n, e ] KeyMetadata: type: object properties: uuid: { type: string } alg: { type: string } created_at: { type: string } required: [uuid, alg, created_at] KeyGenerationReq: type: object properties: alg: { type: string } required: [alg] AuthWithPasswordReq: type: object properties: email: { type: string } password: { type: string } required: [email, password] AuthResp: type: object properties: token: { type: string } user: { $ref: "#/components/schemas/UserDetails" } required: [token, user] User: type: object properties: uuid: { type: string } email: { type: string } password_state: { $ref: "#/components/schemas/UserPasswordState" } enabled: { type: boolean } created_at: { type: string } required: [ uuid, email, password_state, enabled, created_at ] UserDetails: type: object properties: uuid: { type: string } email: { type: string } password_state: { $ref: "#/components/schemas/UserPasswordState" } enabled: { type: boolean } created_at: { type: string } logout_at: { type: string } required: [uuid, email, password_state, enabled, created_at] UserPasswordState: type: string enum: [NotSet, Set, NeedsChange] SetMyPasswordReq: type: object properties: old_password: { type: string } new_password: { type: string } required: [old_password, new_password] UserCreateReq: type: object properties: email: { type: string } password: { type: string } enabled: { type: boolean } required: [email, enabled] UserUpdateReq: type: object properties: email: { type: string } enabled: { type: boolean } required: [ email, enabled ] SetUserPasswordReq: type: object properties: new_password: { type: string } required: [ new_password ] OAuthClient: type: object properties: uuid: { type: string } id: { type: string } name: { type: string } trusted: { type: boolean } created_at: { type: string } required: [uuid, id, name, trusted, created_at] OAuthClientDetails: type: object properties: uuid: { type: string } id: { type: string } name: { type: string } trusted: { type: boolean } primary_secret: { type: string } primary_secret_created_at: { type: string } secondary_secret: { type: string } secondary_secret_created_at: { type: string } redirect_uris: type: array items: { type: string } created_at: { type: string } required: [uuid, id, name, trusted, primary_secret, primary_secret_created_at, redirect_uris, created_at] OAuthClientCreateReq: type: object properties: id: { type: string } name: { type: string } redirect_uris: type: array items: { type: string } trusted: { type: boolean } required: [id, name, trusted] OAuthClientUpdateReq: type: object properties: id: { type: string } name: { type: string } redirect_uris: type: array items: { type: string } trusted: { type: boolean } required: [id, name, trusted] OAuthReq: type: object properties: user_approved: { type: boolean } params: type: object additionalProperties: { type: string } required: [user_approved, params] OAuthResp: type: object properties: redirect_uri: { type: string } oauth_client: { $ref: "#/components/schemas/OAuthClient" } required: [oauth_client] OAuthErrorResp: type: object properties: error: type: string enum: [invalid_request, invalid_client, invalid_grant, unsupported_grant_type, server_error] error_description: { type: string } error_uri: { type: string } required: [error] OAuthTokenReq: type: object properties: grant_type: { type: string } code: { type: string } redirect_uri: { type: string } client_id: { type: string } code_verifier: { type: string } required: [grant_type, code, redirect_uri, client_id] OAuthTokenResp: type: object properties: access_token: { type: string } token_type: { type: string } scope: { type: string } required: [access_token, token_type] OAuthTokenInfoReq: type: object properties: token: { type: string } required: [token] OAuthTokenInfoResp: type: object properties: active: { type: boolean } client_id: { type: string } sub: { type: string } email: { type: string } required: [active] OAuthUserInfo: type: object properties: sub: { type: string } email: { type: string } required: [sub, email]