# Authentication & Security Architecture

## How Users Authenticate

The platform supports three authentication methods.

**OAuth** is the primary path for interactive users. GitHub and Azure AD are supported as OAuth providers. In cloud-hosted deployments, OAuth is handled by a global authentication instance that federates identity across tenants. In self-hosted deployments, the instance runs its own OAuth flow through GoTrue, and administrators register their own OAuth application credentials.

**SAML SSO** provides enterprise single sign-on through identity providers such as Microsoft Entra ID, Okta, or Google Workspace. SAML is enabled by default on all self-hosted deployments. Administrators register their identity provider through the API and provision users — the server auto-detects registered providers from the database. Users must be pre-provisioned before they can authenticate via SSO, as self-registration is disabled by default.

**Application tokens** serve CI/CD pipelines and automated integrations. Tokens are provisioned by an owner through the management API with explicit permission boundaries and expiration. They do not support automatic renewal — expired tokens must be explicitly rotated.

{% @mermaid/diagram content="graph TD
subgraph "Identity Sources"
OAuth\["OAuth<br/>GitHub · Azure AD"]
SAML\["SAML SSO<br/>Entra ID · Okta"]
AppToken\["Application Tokens<br/>CI/CD · Integrations"]
end

```
subgraph "Auth Service"
    GoTrue["GoTrue<br/>Token Issuance"]
end

subgraph "Authorisation"
    Guard["AuthGuard"]
    Membership["Membership Service"]
    RBAC["Role Enforcement"]
end

OAuth --> GoTrue
SAML --> GoTrue
GoTrue --> Guard
AppToken --> Guard
Guard --> Membership
Membership --> RBAC" %}
```

## Request Authorisation

Every API request passes through the AuthGuard before any business logic executes. For JWT tokens, the guard verifies the signature, expiration, and issuer claims, then retrieves the user's team memberships. For application tokens, the guard validates against the token store and checks revocation status.

The role hierarchy has three levels. **Members** can perform standard development operations — builds, deployments to non-production environments, and pull request workflows. **Owners** can manage users, configure integrations, register SSO providers, manage production environments, and provision application tokens. **Application tokens** operate within the permissions granted at provisioning time.

## Cloud and Self-Hosted Modes

In cloud-hosted deployments, a global authentication instance handles OAuth and SAML flows centrally. In self-hosted deployments, the instance runs its own complete auth stack with no external dependencies. Both modes use identical authorisation logic once the JWT is issued.

## Credential Storage

Integration credentials — GitHub App private keys, Azure DevOps PATs, Salesforce connected app secrets — are encrypted at rest using pgcrypto with a key stored in Supabase Vault. The encryption key is generated automatically during server initialisation and stored in the vault, never in environment variables or configuration files.

{% @mermaid/diagram content="graph LR
Register\["API receives<br/>credentials"] --> Encrypt\["pgcrypto<br/>encrypts"]
Encrypt --> Store\["Database stores<br/>ciphertext"]
Store --> Decrypt\["pgcrypto<br/>decrypts"]
Decrypt --> Worker\["Worker holds<br/>in memory"]
Worker --> Clear\["Cleared after<br/>task completes"]

```
VaultKey["Vault Key"] --> Encrypt
VaultKey --> Decrypt" %}
```

All credential types are registered through the integration API, which encrypts and stores them. Credential rotation is supported without downtime — updated credentials take effect on the next task execution without requiring a restart.

## Credential Access at Runtime

When a Hatchet worker receives a task, it requests the specific credentials needed from the server. The server decrypts them and returns them over the internal Docker network. The worker holds credentials in memory only for the task duration and clears them on completion. Credentials are never written to the worker's filesystem and are never shared between tasks.

## Tenant Isolation

Each organisation has its own dedicated database instance, vault, and encryption key. Credentials from one organisation are physically separated from another — there is no shared database or credential store. Each Hatchet worker operates within its own instance's Docker network and can only access its own instance's credentials API.

## Secure Communication

External traffic is TLS-terminated at Caddy, the only service with a host network port binding. All internal services communicate through the Docker bridge network using hostnames that are not resolvable from outside the instance.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp-server/architecture-overview/sfp-server-architecture-overview-beta/authentication-and-security-architecture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
