Skip to content

Authentication

Developer Reference

This page covers internal implementation details. It is not included in the User Guide.

Escher uses a layered authentication model: Cognito OIDC for end-user access, OS Keychain isolation for cloud credentials, and internal network isolation for service-to-service calls.


Architecture overview

Desktop App  ──OIDC token──▶  ALB (Cognito listener rule)

                                   Gateway  ─────────────────────────────────┐
                                       │  internal network (Cloud Map DNS)   │
                              ┌────────┼──────────┐                          │
                              ▼        ▼          ▼                          │
                        Analysis   Playbook    Context                       │
                         Agent      Agent      Engine ──▶ Asset Store        │

                                                               SurrealDB ◀───┘

No service-to-service bearer tokens. Backend components communicate over the private VPC subnet, addressed via AWS Cloud Map DNS (*.escher.internal). Network-level isolation is the security boundary between services.


End-user authentication (desktop app)

The Escher desktop app authenticates users through AWS Cognito with the OIDC authorization code flow.

Flow

  1. On first launch, the desktop app opens a browser window to the Cognito Hosted UI.
  2. The user logs in (email/password or SSO identity provider).
  3. Cognito returns an authorization code. The app exchanges it for id_token, access_token, and refresh_token.
  4. Tokens are stored in the OS Keychain via the v2-tauri-plugin-vault Rust plugin — never written to disk.
  5. The v2-auth-library TypeScript package manages the token lifecycle: refresh before expiry, re-prompt on refresh failure.

Token format

TokenTypeUsed for
id_tokenJWT (RS256)User identity claims — sub, email, groups
access_tokenJWT (RS256)Sent as Authorization: Bearer to Gateway
refresh_tokenOpaqueExchanged for new access_token before expiry (TTL 30 days)

Gateway verification

The ALB Cognito listener rule validates the access_token signature before traffic reaches Gateway. Gateway receives a pre-validated JWT on every request. Gateway extracts sub and groups claims for tenant routing.

ALB listener rule:
  action: authenticate-cognito
  UserPoolArn:    arn:aws:cognito-idp:us-west-1:ACCOUNT:userpool/POOL_ID
  UserPoolClientId: CLIENT_ID
  UserPoolDomain:   escher-auth.auth.us-west-1.amazoncognito.com
  OnUnauthenticatedRequest: deny

Service-to-service authentication

Production (ECS)

All backend services run inside a private VPC subnet and communicate via AWS Cloud Map service discovery. There are no service tokens, no mTLS certificates, and no inter-service Authorization headers.

ServiceDNS name (internal)Port
Analysis Agentanalysis-agent.escher.internal8081
Playbook Agentplaybook-agent.escher.internal8082
Context Enginecontext-engine.escher.internal8001
Asset Storeasset-store.escher.internal8000

Security is enforced at the ECS task security group level — only Gateway's security group has egress permission to the agent ports, and only Context Engine has egress to Asset Store.

Local development (Docker Compose)

Same topology using localhost with fixed port assignments. See Docker Compose for port layout.


LLM API authentication

Analysis Agent and Integrations Agent call the Anthropic API directly using an API key.

bash
# Analysis Agent (Go) — set in ECS task environment / .env locally
ANTHROPIC_API_KEY=sk-ant-...

# Integrations Agent (Go) — same pattern
ANTHROPIC_API_KEY=sk-ant-...
CLASSIFIER_MODEL=claude-haiku-4-5-20251001

The API key is never passed to or through the Gateway. It is loaded by the agent process at startup from its ECS task definition environment variable (stored in AWS Secrets Manager, injected via secretsFrom in the task definition).


Cloud credential handling

Cloud credentials (AWS access keys, Azure tokens, GCP service account keys) are a separate concern from Escher service authentication:

  • Storage: OS Keychain via v2-tauri-plugin-vault (Rust, Tauri plugin)
  • Access: Only the local Tauri plugins (v2-tauri-plugin-scanner, v2-tauri-plugin-estate) read credentials — they never leave the user's machine
  • Transmission: Cloud credentials are never sent to any Escher backend service. The desktop app executes all cloud API calls locally using the stored credentials.
  • Profiles: Each profile has its own credential set; see Profiles

Summary

Auth boundaryMechanismWhere enforced
User → ALBCognito OIDC access_tokenALB listener rule
ALB → GatewayALB passes validated JWTALB/Gateway
Gateway → AgentsInternal VPC networkECS security groups
Agents → Context EngineInternal VPC networkECS security groups
Context Engine → Asset StoreInternal VPC networkECS security groups
Analysis Agent → AnthropicANTHROPIC_API_KEY headerAgent process
Desktop app → cloudLocal credentials from OS KeychainTauri plugins

Next steps

Escher — Agentic CloudOps by Tessell