Skip to main content

Auth Service

The Auth service handles user authentication, session management, API tokens, and service account permissions. It is the single source of truth for identity and authorization across all services.

Features

  • User Management: Create, update, and delete users
  • Session Management: JWT-based authentication with configurable TTL
  • API Tokens: Scoped tokens for programmatic access (ecloud_ prefixed)
  • Service Accounts: Identity-based permission model with NATS-pushed scopes
  • Event Publishing: Publishes user and identity events to NATS
  • Token Validation: Service-to-service endpoint for token revocation and permission checks
  • Rate Limiting: IP-based and user-based rate limiting on login

Architecture

Access Control

Session Auth (website only)

Token and service account management requires a session JWT obtained by logging in through the web dashboard. API tokens cannot be used to create, modify, or delete tokens or service accounts.

Operations requiring session auth:

  • Create / list API tokens
  • Create / list / update / delete service accounts
  • Create / list service account tokens

Token Permission Reads

The auth service is the only service that can read permissions for a given token. Other services (compute, storage) validate API tokens by calling the auth service's /api/tokens/{id}/check endpoint with a service key. This ensures the auth service remains the single source of truth for revocation and scope changes.

Service-to-Service Auth

Internal endpoints use X-Service-Key header authentication. These are not accessible from the public internet.

API Endpoints

Base URL: https://auth.cloud.eddisonso.com

Authentication

MethodPathAuthDescription
POST/api/loginNoneAuthenticate user; returns a session JWT, or requires_2fa: true + a challenge_token when the user has security keys registered
POST/api/logoutSessionInvalidate session
GET/api/sessionSessionGet current session info
POST/api/webauthn/login/beginChallenge tokenBegin WebAuthn 2FA assertion (uses the challenge_token from login)
POST/api/webauthn/login/finishNoneComplete 2FA, returns a session JWT

API Tokens

MethodPathAuthDescription
POST/api/tokensSessionCreate a new API token
GET/api/tokensSessionList user's API tokens
DELETE/api/tokens/{id}SessionRevoke (delete) an API token

Service Accounts

MethodPathAuthDescription
POST/api/service-accountsSessionCreate a service account
GET/api/service-accountsSessionList user's service accounts
GET/api/service-accounts/{id}SessionGet service account details
PUT/api/service-accounts/{id}/scopesSessionUpdate service account scopes
DELETE/api/service-accounts/{id}SessionDelete a service account
POST/api/service-accounts/{id}/tokensSessionCreate a token for a service account
GET/api/service-accounts/{id}/tokensSessionList tokens for a service account

Service-to-Service (internal)

MethodPathAuthDescription
GET/api/tokens/{id}/checkService keyCheck token validity and get scopes
GET/api/usersService keyList all users
GET/api/identity-permissionsService keyList all service account permissions

Admin (requires admin role)

MethodPathAuthDescription
GET/admin/usersAdmin sessionList all users
POST/admin/usersAdmin sessionCreate new user
DELETE/admin/usersAdmin sessionDelete user
GET/admin/sessionsAdmin sessionList active sessions

Settings & Security Keys

MethodPathAuthDescription
GET/api/settings/keysSessionList the user's WebAuthn security keys
POST/api/settings/keys/add/beginSessionBegin registering a new security key
POST/api/settings/keys/add/finishSessionComplete registration of a new security key
POST/api/settings/keys/deleteSessionDelete a security key
POST/api/settings/keys/renameSessionRename a security key
PUT/api/settings/profileSessionUpdate display name
PUT/api/settings/passwordSessionChange password
GET/api/settings/sessionsSessionList the user's active sessions

Docker Registry

MethodPathAuthDescription
GET/v2/tokenHTTP Basic (optional)Issue a short-lived Docker registry token for the requested OCI scope

Token Types

Session JWT

Issued on login, stored as a cookie. Used for web dashboard access.

{
"user_id": "abc123",
"username": "eddison",
"display_name": "Eddison",
"exp": 1707436800,
"iat": 1707350400
}

API Token

Prefixed with ecloud_, contains scoped permissions. Used for programmatic API access.

{
"user_id": "abc123",
"token_id": "tok_xyz",
"type": "api_token",
"scopes": {
"compute.abc123.containers": ["create", "read", "delete"],
"storage.abc123.files": ["read"]
}
}

Scope Format

Scopes follow the pattern: <root>.<user_id>[.<resource>[.<id>]]

RootResources
computecontainers, keys
storagenamespaces, files, registry
networkingdomains, domain-mappings

Allowed actions are per-resource:

RootResourceActions
computecontainerscreate, read, update, delete, start, stop
computekeyscreate, read, delete
storagenamespacescreate, read, update, delete
storagefilescreate, read, delete
storageregistrypush, pull, delete
networkingdomainscreate, read, delete
networkingdomain-mappingscreate, read, delete

Scopes cascade — compute.uid.containers with read grants read access to all containers, while compute.uid.containers.abc with read grants access to only that container.

Database Schema

CREATE TABLE users (
id SERIAL PRIMARY KEY,
public_id TEXT UNIQUE NOT NULL,
username TEXT UNIQUE NOT NULL,
display_name TEXT,
password_hash TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE sessions (
id TEXT PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
expires_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE api_tokens (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
token_hash TEXT NOT NULL,
scopes JSONB NOT NULL DEFAULT '{}',
expires_at BIGINT DEFAULT 0,
last_used_at BIGINT DEFAULT 0,
service_account_id TEXT REFERENCES service_accounts(id),
created_at BIGINT NOT NULL
);

CREATE TABLE service_accounts (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
scopes JSONB NOT NULL DEFAULT '{}',
version BIGINT DEFAULT 1,
created_at BIGINT NOT NULL
);

Events Published

SubjectDescription
auth.user.{id}.createdNew user registered
auth.user.{id}.deletedUser deleted
auth.user.{id}.updatedUser profile updated
auth.session.{id}.createdUser logged in
auth.session.{id}.invalidatedUser logged out
auth.identity.{sa_id}.updatedService account permissions changed
auth.identity.{sa_id}.deletedService account deleted

Configuration

FlagDescriptionDefault
-addrHTTP listen address:8080
-session-ttlSession lifetime24h
-log-serviceLog service gRPC address(disabled)
Env VariableDescription
DATABASE_URLPostgreSQL connection string
JWT_SECRETSecret for signing JWTs
ADMIN_USERNAMEAdmin user identifier
DEFAULT_USERNAMEDefault user to create on startup
DEFAULT_PASSWORDPassword for default user
NATS_URLNATS server URL
SERVICE_API_KEYShared key for service-to-service auth

Health Check

GET /healthz → 200 OK