openapi: 3.0.3
info:
    title: auth
    description: The Auth Service is the single source of truth for all accounts and their permissions, managing authentication and access control across the platform. It maintains efficiency at scale by issuing access tokens to accounts when they log into the platform and providing public keys for other services to verify them.
    version: 1.0.0
servers:
    - url: https://auth.platform.arb.inc
paths:
    /:
        get:
            summary: Get basic service information
            description: Returns a plain text welcome message with the service name and creation date.
            operationId: getRoot
            responses:
                '200':
                    description: Successfully retrieved welcome message.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Welcome to the auth service. Created on July 17, 2025 by Al Beebe
            tags:
                - /
    /authenticate/basic-auth:
        post:
            summary: Authenticate user with email and password
            description: Authenticates a user using basic credentials and returns an access token and refresh token upon success.
            operationId: postAuthenticateBasicAuth
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                                - password
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: Email address of the user.
                                    example: user@example.com
                                password:
                                    type: string
                                    description: Password for the user account.
                                    example: strongpassword123
            responses:
                '200':
                    description: Authentication successful.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    accessToken:
                                        type: string
                                        description: JWT access token.
                                        example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                                    refreshToken:
                                        type: string
                                        description: Refresh token for session renewal.
                                        example: 9fd0b18a-6b3c-4e5f-9422-893ef77a07ea
                                    validForSeconds:
                                        type: integer
                                        format: int64
                                        description: Lifetime of the access token in seconds.
                                        example: 3600
                '401':
                    description: Authentication failed due to invalid password.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Invalid password
                '403':
                    description: Email is not verified.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Email is not verified
                '404':
                    description: Account not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account not found
                '422':
                    description: Account does not have a password or has exceeded failed login attempts.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account doesn't have a password
                '423':
                    description: Account is locked.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account is locked
            tags:
                - authenticate
    /authenticate/google:
        post:
            summary: Authenticate with Google ID Token
            description: Authenticates a user using a Google ID token. Returns access and refresh tokens upon successful login.
            operationId: postAuthenticateGoogle
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - idToken
                            properties:
                                idToken:
                                    type: string
                                    description: Google-issued ID token.
                                    example: "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk2MjM..."
            responses:
                '200':
                    description: Successfully authenticated.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    accessToken:
                                        type: string
                                        description: The JWT access token.
                                        example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                                    refreshToken:
                                        type: string
                                        description: A long-lived refresh token.
                                        example: "dGhpc19pc19hX3JlZnJlc2hfdG9rZW4"
                                    validForSeconds:
                                        type: integer
                                        description: Duration (in seconds) that the access token is valid for.
                                        example: 3600
                '401':
                    description: Invalid ID token.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: "'idToken' is not valid"
                '403':
                    description: Email is not verified.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: "Email is not verified"
                '404':
                    description: No user account found for the given email.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: "Account not found"
                '423':
                    description: The account is locked.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: "Account is locked"
            tags:
                - authenticate
    /authenticate/service-account:
        post:
            summary: Authenticate a service using a service account ID token
            description: Validates a Google-issued ID token and returns an access token if the service account is valid and recognized.
            operationId: authenticateServiceAccount
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - id_token
                            properties:
                                id_token:
                                    type: string
                                    description: Google-issued ID token for the service account.
                                    example: "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
            responses:
                '200':
                    description: Access token successfully issued.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    access_token:
                                        type: string
                                        description: The generated access token for the authenticated session.
                                        example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                                    valid_for_seconds:
                                        type: integer
                                        description: Token validity duration in seconds.
                                        example: 3600
                '401':
                    description: Unauthorized - token invalid or account not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: id_token failed validation
            tags:
                - authenticate
    /internal/organization-users:
        post:
            summary: Get users for an organization
            description: Returns the users that belong to a specific organization.
            operationId: postInternalOrganizationUsers
            security:
                - bearerAuth: []
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - organizationID
                            properties:
                                organizationID:
                                    type: string
                                    format: uuid
                                    description: The ID of the organization to look up.
                                    example: "c17c3433-81b3-4096-90e0-9fbb32c06204"
            responses:
                '200':
                    description: Users successfully retrieved.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    users:
                                        type: array
                                        description: List of users in the organization.
                                        example:
                                            - id: "8b7f5a1e-3c2d-4e9a-9b33-2a1f7f8a9c10"
                                            - id: "13af1f0e-4d6a-4207-8a2f-2f1e3b4c5d6e"
                                        items:
                                            type: object
                                            properties:
                                                id:
                                                    type: string
                                                    format: uuid
                                                    description: User ID.
                                                    example: "8b7f5a1e-3c2d-4e9a-9b33-2a1f7f8a9c10"
            tags:
                - internal
    /organizations/create:
        post:
            summary: Create a new organization
            description: Creates a new organization for the authenticated user. Users are limited to a maximum number of organizations they can create.
            operationId: createOrganization
            security:
                - bearerAuth: []
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - name
                            properties:
                                name:
                                    type: string
                                    description: The name of the organization to create.
                                    maxLength: 100
                                    example: My Organization
            responses:
                '200':
                    description: Organization successfully created.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    organizationId:
                                        type: string
                                        description: ID of the created organization.
                                        example: "3f3cdd5b-f823-4e6e-8de9-6132dfe4c9c0"
                '409':
                    description: Organization creation limit reached.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Organization creation limit of 2 reached. You cannot create additional organizations at this time.
            tags:
                - organizations
    /organizations/list:
        post:
            summary: List user's organizations
            description: Retrieves all organizations that the authenticated user is a member of.
            operationId: listOrganizations
            security:
                - bearerAuth: []
            responses:
                '200':
                    description: Successfully retrieved the user's organizations.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    organizations:
                                        type: array
                                        items:
                                            type: object
                                            properties:
                                                id:
                                                    type: string
                                                    description: Unique ID of the organization.
                                                    example: "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                                                created:
                                                    type: string
                                                    format: date-time
                                                    description: Time the user was added to the organization.
                                                    example: "2023-08-14T15:52:01Z"
                                                invitedBy:
                                                    type: string
                                                    description: ID of the user who invited them to the organization.
                                                    example: "b5212d78-f6d2-43c0-bef1-933201e9fdd6"
            tags:
                - organizations
    /sessions/attach-roles:
        post:
            summary: Attach roles to the current session
            description: Verifies the TOTP passcode and enables session roles for the current user session.
            operationId: attachSessionRoles
            security:
                - bearerAuth: []
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - totpPasscode
                            properties:
                                totp_passcode:
                                    type: string
                                    description: The TOTP code generated by the user's authenticator app.
                                    example: "123456"
            responses:
                '200':
                    description: Session roles successfully enabled.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: session roles successfully enabled; please refresh the session
                '403':
                    description: Invalid passcode.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Passcode is invalid
                '409':
                    description: TOTP is not configured for the user.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: TOTP is not configured
                '422':
                    description: User locked out due to too many failed attempts.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: You have been locked out for security purposes
            tags:
                - sessions
    /sessions/logout:
        post:
            summary: Log out a user session
            description: Invalidates a user session by deleting the associated refresh token.
            operationId: postSessionsLogout
            security:
                - bearerAuth: []
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - refreshToken
                            properties:
                                refreshToken:
                                    type: string
                                    description: The refresh token to invalidate.
                                    example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
            responses:
                '200':
                    description: Successfully logged out the session.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Successfully logged out the session
            tags:
                - sessions
    /sessions/refresh:
        post:
            summary: Refresh user session
            description: Generates a new access token using a valid refresh token.
            operationId: refreshSession
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - refreshToken
                            properties:
                                refreshToken:
                                    type: string
                                    description: The refresh token to use for refreshing the session.
                                    example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
            responses:
                '200':
                    description: Session successfully refreshed.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    accessToken:
                                        type: string
                                        description: The newly generated access token.
                                        example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                                    refreshToken:
                                        type: string
                                        description: The updated refresh token.
                                        example: "dGhpc2lzbmV3cmVmcmVzaHRva2Vu"
                                    validForSeconds:
                                        type: integer
                                        description: Duration in seconds for which the access token is valid.
                                        example: 3600
                '401':
                    description: Session does not exist or is invalid.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: session does not exist
            tags:
                - sessions
    /sessions/switch-organization:
        post:
            summary: Switch organization for current session
            description: Updates the current session to switch the active organization.
            operationId: switchOrganization
            security:
                - bearerAuth: []
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                organizationId:
                                    type: string
                                    description: The ID of the organization to switch to. If omitted or empty, the session organization will be cleared.
                                    example: "af21b50b-90ee-461d-9a84-5a152f65af3b"
            responses:
                '200':
                    description: Organization successfully switched for the session.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: session organization successfully switched; please refresh the session
                '404':
                    description: User is not a member of the specified organization.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: User is not a member of the organization
            tags:
                - sessions
    /users/create/basic-auth:
        post:
            summary: Create a new user with basic authentication
            description: Creates a user account using an email and password.
            operationId: createBasicAuthUser
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                                - password
                                - firstName
                                - termsOfService
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: User's email address.
                                    example: user@example.com
                                password:
                                    type: string
                                    description: >
                                        User's password. Must meet the following security requirements:

                                          - At least 8 characters long
                                          - At least one uppercase letter
                                          - At least one lowercase letter
                                          - At least one digit
                                          - At least one special character
                                    example: MySecurePassword123!
                                firstName:
                                    type: string
                                    description: User's first name.
                                    example: Jane
                                lastName:
                                    type: string
                                    nullable: true
                                    description: User's last name (optional).
                                    example: Doe
                                termsOfService:
                                    type: string
                                    format: date-time
                                    description: RFC3339 timestamp indicating when the user accepted the Terms of Service.
                                    example: 2025-02-19T16:00:00Z
            responses:
                '200':
                    description: Account successfully created.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account successfully created
                '409':
                    description: A user account with the provided email already exists.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: An account with this email already exists
            tags:
                - users
    /users/create/google:
        post:
            summary: Create a user account using Google ID token
            description: Creates a new user account by validating a Google ID token. Requires a valid token and basic user information.
            operationId: createUserWithGoogle
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - idToken
                                - firstName
                                - termsOfService
                            properties:
                                idToken:
                                    type: string
                                    description: Google ID token obtained from client.
                                    example: "eyJhbGciOiJSUzI1NiIsImtpZCI6..."
                                firstName:
                                    type: string
                                    description: User's first name.
                                    example: "Alice"
                                lastName:
                                    type: string
                                    nullable: true
                                    description: User's last name.
                                    example: "Johnson"
                                termsOfService:
                                    type: string
                                    format: date-time
                                    description: RFC3339 timestamp when user agreed to terms.
                                    example: "2025-02-19T16:00:00Z"
            responses:
                '200':
                    description: Account successfully created.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account successfully created
                '401':
                    description: Invalid or expired Google ID token.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: "'id_token' is not valid"
                '409':
                    description: An account with this email already exists.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: An account with this email already exists
            tags:
                - users
    /users/email/confirm:
        post:
            summary: Confirm user's email address
            description: Verifies the user's email using a verification code and marks the email as verified if successful.
            operationId: confirmUserEmail
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                                - verificationCode
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: The email address to verify.
                                    example: user@example.com
                                verificationCode:
                                    type: string
                                    description: The verification code sent to the user's email.
                                    example: "123456"
            responses:
                '200':
                    description: Email successfully verified.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Successfully verified
                '403':
                    description: Too many failed attempts to verify the code. Must request a new code.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Too many failed attempts
                '404':
                    description: Verification code has expired.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Request a new verification code
                '422':
                    description: Incorrect verification code.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Verification code is incorrect
            tags:
                - users
    /users/email/send-verification:
        post:
            summary: Send email verification code
            description: Sends a verification code to the user's email address if it is unverified.
            operationId: sendEmailVerification
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: The email address to send the verification code to.
                                    example: user@example.com
            responses:
                '200':
                    description: Verification code successfully sent.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    codeLength:
                                        type: integer
                                        description: Length of the verification code sent.
                                        example: 6
                                    validForSeconds:
                                        type: integer
                                        description: Duration in seconds the code is valid for.
                                        example: 600
                                    retryInSeconds:
                                        type: integer
                                        description: Minimum wait time before another request can be made.
                                        example: 60
                '404':
                    description: Account not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account not found
                '409':
                    description: Email is already verified.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Email is already verified
                '423':
                    description: Account is locked.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account is locked
                '429':
                    description: Too many requests.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Too many requests
            tags:
                - users
    /users/password/reset:
        post:
            summary: Reset user password
            description: Resets the user's password using a verification code sent via email.
            operationId: resetUserPassword
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                                - verificationCode
                                - password
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: The user's email address.
                                    example: user@example.com
                                verificationCode:
                                    type: string
                                    description: Verification code sent to the user's email.
                                    example: 123456
                                password:
                                    type: string
                                    description: New password to set for the user.
                                    example: MyStrongPassw0rd!
            responses:
                '200':
                    description: Password successfully reset.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Successfully reset the password
                '403':
                    description: Too many failed verification attempts.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Too many failed attempts
                '404':
                    description: User not found or verification code not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Request a new verification code
                '422':
                    description: Verification code is incorrect.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Verification code is incorrect
            tags:
                - users
    /users/password/send-verification:
        post:
            summary: Send password reset verification code
            description: Sends a verification code to the user's email for resetting the password.
            operationId: sendPasswordResetVerification
            requestBody:
                required: true
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - email
                            properties:
                                email:
                                    type: string
                                    format: email
                                    description: The email address associated with the user account.
                                    example: user@example.com
            responses:
                '200':
                    description: Verification code sent successfully.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    codeLength:
                                        type: integer
                                        description: The length of the verification code.
                                        example: 6
                                    validForSeconds:
                                        type: integer
                                        description: Number of seconds the verification code is valid for.
                                        example: 600
                                    retryInSeconds:
                                        type: integer
                                        description: Number of seconds before another code can be requested.
                                        example: 300
                '404':
                    description: Account not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account not found
                '423':
                    description: Account is locked.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Account is locked
                '429':
                    description: Too many requests.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Too many requests
            tags:
                - users
    /users/roles/list:
        post:
            summary: List available roles for the user
            description: Returns the list of roles that the authenticated user is allowed to assume. These roles can be added to their session.
            operationId: listAvailableUserRoles
            security:
                - bearerAuth: []
            responses:
                '200':
                    description: Successfully retrieved available roles for the user.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    roles:
                                        type: array
                                        items:
                                            type: string
                                        description: A list of roles available to the user.
                                        example: ["admin", "viewer"]
                '401':
                    description: Unauthorized - invalid or missing access token.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: unauthorized
                '403':
                    description: Forbidden - user ID not found in token claims.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: user ID not found in token claims
            tags:
                - users
    /users/totp/create:
        post:
            summary: Create a new TOTP credential for a user
            description: Creates a TOTP credential for the authenticated user. If a credential already exists and has been used, the creation will be rejected.
            operationId: createTOTP
            security:
                - bearerAuth: []
            responses:
                '200':
                    description: TOTP credential successfully created.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    secret:
                                        type: string
                                        description: The shared secret for the TOTP credential.
                                        example: "JBSWY3DPEHPK3PXP"
                                    issuer:
                                        type: string
                                        description: The name of the TOTP issuer.
                                        example: "Parkflow"
                                    accountName:
                                        type: string
                                        description: The account name associated with the TOTP.
                                        example: "user@example.com"
                                    algorithm:
                                        type: string
                                        description: The algorithm used for TOTP generation.
                                        example: "SHA1"
                                    digits:
                                        type: integer
                                        description: Number of digits in the TOTP code.
                                        example: 6
                                    period:
                                        type: integer
                                        description: Time period in seconds for each TOTP code.
                                        example: 30
                '409':
                    description: TOTP credential already exists and has been used.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Credential already exists
            tags:
                - users
    /users/totp/read:
        post:
            summary: Read user's TOTP credential
            description: Retrieves the TOTP credential metadata for the authenticated user.
            operationId: readUserTOTP
            security:
                - bearerAuth: []
            responses:
                '200':
                    description: Successfully retrieved TOTP credential.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    created:
                                        type: string
                                        format: date-time
                                        description: Timestamp when the credential was created.
                                        example: "2023-08-15T14:12:00Z"
                                    updated:
                                        type: string
                                        format: date-time
                                        description: Timestamp when the credential was last updated.
                                        example: "2024-01-10T09:30:00Z"
                                    digits:
                                        type: integer
                                        description: Number of digits in the TOTP code.
                                        example: 6
                                    usageCount:
                                        type: integer
                                        description: Number of times the TOTP credential has been used.
                                        example: 42
                '404':
                    description: TOTP credential not found.
                    content:
                        text/plain:
                            schema:
                                type: string
                                example: Credential not found
            tags:
                - users
components:
    securitySchemes:
        bearerAuth:
            type: http
            description: access token
            scheme: bearer
            bearerFormat: JWT
tags:
    - name: /
    - name: authenticate
    - name: internal
    - name: organizations
    - name: sessions
    - name: users
