Files
git.stella-ops.org/docs/modules/release-orchestrator/security/auth.md

9.7 KiB

Authentication & Authorization

Authentication Methods

OAuth 2.0 for Human Users

┌──────────────────────────────────────────────────────────────────────────────┐
│                    OAUTH 2.0 AUTHORIZATION CODE FLOW                          │
│                                                                              │
│  ┌──────────┐                          ┌──────────────┐                      │
│  │  Browser │                          │   Authority   │                      │
│  └────┬─────┘                          └──────┬───────┘                      │
│       │                                       │                               │
│       │ 1. Login request                      │                               │
│       │ ────────────────────────────────────► │                               │
│       │                                       │                               │
│       │ 2. Redirect to IdP                    │                               │
│       │ ◄──────────────────────────────────── │                               │
│       │                                       │                               │
│       │ 3. User authenticates at IdP          │                               │
│       │ ─────────────────────────────────►    │                               │
│       │                                       │                               │
│       │ 4. IdP callback with code             │                               │
│       │ ◄──────────────────────────────────── │                               │
│       │                                       │                               │
│       │ 5. Exchange code for tokens           │                               │
│       │ ────────────────────────────────────► │                               │
│       │                                       │                               │
│       │ 6. Access token + refresh token       │                               │
│       │ ◄──────────────────────────────────── │                               │
│       │                                       │                               │
└──────────────────────────────────────────────────────────────────────────────┘

mTLS for Agents

Agents authenticate using mutual TLS with certificates issued by Stella's internal CA.

Registration Flow:

  1. Admin generates one-time registration token
  2. Agent starts with registration token
  3. Agent submits CSR (Certificate Signing Request)
  4. Authority issues certificate signed by Stella CA
  5. Agent uses certificate for all subsequent requests

API Keys for Service-to-Service

External services can use API keys for programmatic access:

  • Keys are tenant-scoped
  • Keys can have restricted permissions
  • Keys can have expiration dates
  • Key usage is audited

JWT Token Structure

Access Token Claims

interface AccessTokenClaims {
  // Standard claims
  iss: string;          // "https://authority.stella.local"
  sub: string;          // User ID
  aud: string[];        // ["stella-api"]
  exp: number;          // Expiration timestamp
  iat: number;          // Issued at timestamp
  jti: string;          // Unique token ID

  // Custom claims
  tenant_id: string;
  roles: string[];
  permissions: Permission[];
  email?: string;
  name?: string;
}

Token Lifetimes

Token Type Lifetime Refresh
Access Token 15 minutes Via refresh token
Refresh Token 7 days Rotated on use
Agent Token 1 hour Via mTLS connection
API Key Configurable Not refreshed

Authorization Model

Resource Types

type ResourceType =
  | "environment"
  | "release"
  | "promotion"
  | "target"
  | "agent"
  | "workflow"
  | "plugin"
  | "integration"
  | "evidence";

Action Types

type ActionType =
  | "create"
  | "read"
  | "update"
  | "delete"
  | "execute"
  | "approve"
  | "deploy"
  | "rollback";

Permission Structure

interface Permission {
  resource: ResourceType;
  action: ActionType;
  scope?: PermissionScope;
  conditions?: Condition[];
}

type PermissionScope =
  | "*"                              // All resources
  | { environmentId: UUID }          // Specific environment
  | { labels: Record<string, string> }; // Label-based

Built-in Roles

Role Description Key Permissions
admin Full access All permissions
release_manager Manage releases and promotions Create releases, request promotions
deployer Execute deployments Approve promotions (where allowed), view releases
approver Approve promotions Approve promotions (SoD respected)
viewer Read-only access Read all resources
agent Agent service account Execute deployment tasks

Role Definitions

const roles = {
  admin: {
    permissions: [
      { resource: "*", action: "*" }
    ]
  },
  release_manager: {
    permissions: [
      { resource: "release", action: "create" },
      { resource: "release", action: "read" },
      { resource: "release", action: "update" },
      { resource: "promotion", action: "create" },
      { resource: "promotion", action: "read" },
      { resource: "environment", action: "read" },
      { resource: "workflow", action: "read" },
      { resource: "workflow", action: "execute" }
    ]
  },
  deployer: {
    permissions: [
      { resource: "release", action: "read" },
      { resource: "promotion", action: "read" },
      { resource: "promotion", action: "approve" },
      { resource: "environment", action: "read" },
      { resource: "target", action: "read" },
      { resource: "agent", action: "read" }
    ]
  },
  approver: {
    permissions: [
      { resource: "promotion", action: "read" },
      { resource: "promotion", action: "approve" },
      { resource: "release", action: "read" },
      { resource: "environment", action: "read" }
    ]
  },
  viewer: {
    permissions: [
      { resource: "*", action: "read" }
    ]
  }
};

Environment-Scoped Permissions

Permissions can be scoped to specific environments:

// User can approve promotions only to staging
{
  resource: "promotion",
  action: "approve",
  scope: { environmentId: "staging-env-id" }
}

// User can deploy only to targets with specific labels
{
  resource: "target",
  action: "deploy",
  scope: { labels: { "tier": "frontend" } }
}

Separation of Duties (SoD)

When SoD is enabled for an environment:

  • The user who requested a promotion cannot approve it
  • The user who created a release cannot be the sole approver
  • Approval records include SoD verification status
interface ApprovalValidation {
  promotionId: UUID;
  approverId: UUID;
  requesterId: UUID;
  sodRequired: boolean;
  sodSatisfied: boolean;
  validationResult: "valid" | "self_approval_denied" | "sod_violation";
}

Permission Checking Algorithm

async function checkPermission(
  userId: UUID,
  resource: ResourceType,
  action: ActionType,
  resourceId?: UUID
): Promise<boolean> {
  // 1. Get user's roles and direct permissions
  const userRoles = await getUserRoles(userId);
  const userPermissions = await getUserPermissions(userId);

  // 2. Expand role permissions
  const rolePermissions = userRoles.flatMap(r => roles[r].permissions);
  const allPermissions = [...rolePermissions, ...userPermissions];

  // 3. Check for matching permission
  for (const perm of allPermissions) {
    if (matchesResource(perm.resource, resource) &&
        matchesAction(perm.action, action) &&
        matchesScope(perm.scope, resourceId) &&
        evaluateConditions(perm.conditions)) {
      return true;
    }
  }

  return false;
}

function matchesResource(pattern: string, resource: string): boolean {
  return pattern === "*" || pattern === resource;
}

function matchesAction(pattern: string, action: string): boolean {
  return pattern === "*" || pattern === action;
}

API Authorization Headers

All API requests require:

Authorization: Bearer <access_token>

For agent requests (over mTLS):

X-Agent-Id: <agent_id>
Authorization: Bearer <agent_token>

Permission Denied Response

{
  "success": false,
  "error": {
    "code": "PERMISSION_DENIED",
    "message": "User does not have permission to approve promotions to production",
    "details": {
      "resource": "promotion",
      "action": "approve",
      "scope": { "environmentId": "prod-env-id" },
      "requiredRoles": ["admin", "approver"],
      "userRoles": ["viewer"]
    }
  }
}

References