Security Model
Overview
Atlas Auth Guard implements a multi-layered security model combining:
Authentication: Verify user identity (Google OAuth, JWT, API Keys)
Authorization: Verify user has permission to access resources
Tenant Isolation: Ensure users only access resources within their organization
Hierarchy
Organization
└── Team (service access policies)
└── Project (data isolation)
└── User (membership)Key Principles
Users belong to Teams: A user must be a team member before accessing team resources
Projects belong to Teams: A user must be a team member before joining a project
Teams have Service Policies: Teams define which backend services they can access
Projects provide Data Isolation: Each project has isolated data within a service
Authentication Methods
1. JWT Token (User Authentication)
JWT tokens are issued after Google OAuth login and contain:
User identity (
sub,email,name)Organization context (
org_id,org_name)Team context (
team_id,team_name)Project context (
project_id,project_name)Roles (
global_role,team_role,project_role)Permissions (list of allowed actions)
2. API Key (Service/CLI Authentication)
API keys are scoped to a team and optionally a project:
Created by team/project admins
Bound to team_id at creation time
Can be further scoped to project_id
Have expiration dates
3. Service Account (S2S Authentication)
Google Cloud service accounts for service-to-service communication:
Uses Google OIDC tokens
Authorized via service policies in database
Endpoint-level access control
Role Hierarchy
Role Groups & Levels
Role-Permission Matrix
Global Scope Roles
super_admin
✅
✅
✅
✅
✅
✅
✅
Organization Scope Roles
org_admin
✅
✅
❌
✅
✅
✅
✅
member
✅
❌
❌
❌
❌
❌
❌
Team Scope Roles
team_admin
✅
✅
✅
✅
✅
✅
❌
team_member
✅
❌
❌
❌
✅
❌
❌
Project Scope Roles
project_admin
✅
✅
❌
✅
✅
✅
❌
editor
✅
✅
❌
❌
✅
❌
❌
viewer
✅
❌
❌
❌
❌
❌
❌
Access Rules
Security Check Bypass
super_admin
✅ Yes
✅ Yes
Platform-wide access
org_admin
✅ Yes
✅ Yes
Organization-wide access
member
❌ No
❌ No
Must have team context
Resource Visibility (/me/teams and /me/projects)
/me/teams and /me/projects)global_role
team_role
/me/teams
/me/projects
super_admin
-
ALL teams in org
ALL projects in org
org_admin
-
ALL teams in org
ALL projects in org
member
team_admin
Own teams
ALL projects in own teams
member
team_member
Own teams
ALL projects in own teams
member
-
Own teams
Only explicit memberships
Effective Role Calculation
When a user accesses a resource, their effective role determines permissions. The principle is most specific wins.
Precedence Order (Most Specific Wins)
Key Distinction: Access Checks vs Effective Role
Access Checks
Team policy, membership verification
super_admin, org_admin
Effective Role
Determines permissions for a resource
Nobody - most specific wins
Global roles bypass ACCESS CHECKS but do NOT override explicit role assignments.
Decision Flow
Precedence Examples
Super admin, no team/project role
super_admin
-
-
super_admin
Global fallback
Super admin, team member
super_admin
team_member
-
team_member
Team role wins
Super admin, explicit viewer
super_admin
team_admin
viewer
viewer
Project role wins
Org admin, no explicit roles
org_admin
-
-
org_admin
Global fallback
Team admin, no project role
member
team_admin
-
team_admin
Team role wins
Team admin, explicit viewer
member
team_admin
viewer
viewer
Project role wins
Team member, explicit editor
member
team_member
editor
editor
Project role wins
Only org member
member
-
-
member
Global fallback
Real-World Scenario
You are:
Global role:
super_adminTeam X role:
team_memberProject Y role:
project_admin
What happens:
Project Y (explicit role)
project_admin
Explicit project role wins
Project Z (in Team X, no explicit role)
team_member
Team role applies
Project W (in Team B, no membership)
super_admin
No explicit role, global fallback + bypasses access checks
Important Notes
Explicit project roles ALWAYS win for that specific project
Even super_admin can be restricted to viewer on sensitive projects
Global roles bypass ACCESS CHECKS, not role assignments
super_admin can access any resource (bypasses team policy, membership checks)
But if they have explicit team/project roles, those determine permissions
Team roles apply to ALL projects in that team
Unless overridden by explicit project role
This follows industry standards:
AWS IAM: Resource policy > Identity policy
Kubernetes: RoleBinding > ClusterRoleBinding
Google Cloud: Resource-level > Folder > Org
Authorization Flow
Request Flow
Security Checks (in order)
Authentication (401 if fails)
Validate JWT signature and expiration
Or validate API key hash and status
User Status Check (403 if fails)
User must be
active(notsuspended,disabled, etc.)
Team Policy Enforcement (403 if fails)
Bypassed for:
super_admin,org_adminTeam must have access to the requested service
Configured via
team_policiestable
Team/Project Membership Verification (403 if fails)
Bypassed for:
super_admin,org_adminUser must be a member of the team in their JWT
If project_id in JWT, user must be a member (or team_admin/team_member in that team)
Prevents token manipulation attacks
S2S Authorization (for service accounts)
Service account must be authorized for target service
Endpoint-level access control
Rate Limiting
Applied after authorization
Per-user or per-API-key limits
Team Policies
Team policies control which services a team can access.
Database Schema
Example
Behavior
["atlas-ai-oss-svc"]
/v1/atlas-ai-oss-svc/...
✅ Allowed
["atlas-ai-oss-svc"]
/v1/cli-eval/...
❌ 403 Forbidden
enabled: false
Any service
❌ 403 Forbidden
No policy exists
Any service
❌ 403 Forbidden
Project Isolation
Projects provide data isolation within a service.
How It Works
Auth Guard verifies user is a project member
Auth Guard injects
X-Project-IDheaderBackend Service filters data by
X-Project-ID
Backend Responsibility
Backend services MUST filter data by X-Project-ID:
Access Scenarios
User in Team A, Project X
Access Project X data
✅ Allowed
User in Team A, Project X
Access Project Y data
❌ 403 (not member)
User in Team A only (no project)
Access team-level API
✅ Allowed
User in Team A only (no project)
Access Project X data
❌ 403 (not member)
Membership Rules
Adding Users to Teams
Any user can be added to a team within their organization.
Adding Users to Projects
Security Rule: A user MUST be a team member before being added to a project.
If user is not a team member, the API returns:
Removing Users
Removing a user from a team automatically removes them from all projects in that team
Removing a user from a project does not affect team membership
Role-Based Access Control (RBAC)
Roles Hierarchy
Role Permissions
super_admin
All permissions
org_admin
Manage org, teams, users
team_admin
Manage team members, projects
project_admin
Manage project members, settings
editor
Read/write project data
viewer
Read-only access
Headers Injected by Auth Guard
The following headers are added to every request forwarded to backend services:
Core Headers
X-User-ID
User's unique ID
google-oauth2|123456789
X-User-Name
User's display name
John Doe
X-Org-ID
Organization ID
uuid
X-Org-Name
Organization name
Turing
X-Team-ID
Team ID
uuid
X-Team-Name
Team name
Engineering
X-Project-ID
Project ID (if applicable)
uuid
X-Project-Name
Project name (if applicable)
Alpha
X-Request-ID
Unique request ID for tracing
uuid
Role Headers
X-Effective-Role
Calculated role based on precedence
team_admin
X-Global-Role
User's global role (raw)
member
X-Team-Role
User's role in team (raw)
team_admin
X-Project-Role
User's role in project (raw)
editor
X-Permissions
Permissions for effective role
["read:project", "write:project"]
Understanding X-Effective-Role
X-Effective-Role is the calculated role based on the precedence order:
Example scenarios:
super_admin
-
-
super_admin
ALL permissions
member
team_admin
-
team_admin
team_admin permissions
member
team_admin
viewer
viewer
viewer permissions
member
team_member
editor
editor
editor permissions
Backend services should use X-Effective-Role and X-Permissions for authorization decisions, not the raw role headers.
Security Best Practices
For Consumer Applications
Always validate origin in postMessage handlers
Store tokens securely (httpOnly cookies preferred over localStorage)
Handle token expiration gracefully
Use specific team/project context when available
For Backend Services
Always filter by X-Project-ID for project-scoped data
Validate X-Team-ID matches expected team for team-scoped operations
Log X-Request-ID for audit trails
Don't trust client-provided IDs - use header values from Auth Guard
For Administrators
Regularly audit team policies to ensure least privilege
Review API key usage and rotate expired keys
Monitor failed authentication attempts
Keep team/project membership up to date
Troubleshooting
403 Forbidden: Team Policy
Fix: Add the service to the team's policy via admin API.
403 Forbidden: Not Team Member
Fix: User needs to be added to the team, or re-login with correct team context.
403 Forbidden: Not Project Member
Fix: User needs to be added to the project by a team/project admin.
Last updated