# Auth Flow

dpg has no user-facing authentication. "Auth" here means AWS credential resolution and Bedrock authorization.

---

## AWS Credential Resolution

```mermaid
flowchart TD
    START["App startup\nmain.py import"]

    START --> DOTENV["load_dotenv(ROOT_DIR/.env, override=False)\nSets env vars only if not already in shell"]

    DOTENV --> CONFIG["shared/config.py imports\nBEDROCK_REGION, model IDs, timeouts\nresolved from os.getenv() at import time"]

    CONFIG --> CLIENT_TYPE{"Which client\nis needed?"}

    CLIENT_TYPE -->|"step-02, step-03"| RAW["BedrockLLMClient.__init__()\nbedrock_raw_client.py\nboto3.client('bedrock-runtime',\n  aws_access_key_id, aws_secret_access_key,\n  region_name, config=botocore.Config)"]

    CLIENT_TYPE -->|"step-04, step-05"| CHAT["build_chat_model()\nbedrock_client.py\nboto3.Session created"]

    CHAT --> CRED_CHECK{"Credentials\nfound?"}
    CRED_CHECK -->|"Access key + secret in env"| SESSION_KEYS["boto3.Session(\n  aws_access_key_id,\n  aws_secret_access_key,\n  aws_session_token (optional),\n  region_name)"]

    CRED_CHECK -->|"AWS_PROFILE in env"| SESSION_PROFILE["boto3.Session(\n  profile_name,\n  region_name)"]

    CRED_CHECK -->|"Neither"| SESSION_DEFAULT["boto3.Session(region_name)\nrelies on default chain:\n~/.aws/credentials\nor IAM role"]

    SESSION_KEYS --> VERIFY["session.get_credentials()"]
    SESSION_PROFILE --> VERIFY
    SESSION_DEFAULT --> VERIFY

    VERIFY -->|"None"| ERROR["raise RuntimeError(\n'AWS credentials were not found.')"]
    VERIFY -->|"Credentials"| CHAT_MODEL["ChatBedrockConverse(\n  model=resolved_model_id,\n  region_name,\n  temperature=0,\n  config=botocore.Config(\n    connect_timeout=30s,\n    read_timeout=600s,\n    retries={'max_attempts': 2}))\n  tcp_keepalive=True"]

    CHAT_MODEL --> READY["Client ready\nfor invoke() calls"]

    RAW --> READY

    style ERROR fill:#ffdddd,stroke:#cc0000
    style READY fill:#ddffdd,stroke:#00aa00
```

---

## Bedrock Authorization — What IAM Permissions Are Needed

```mermaid
flowchart LR
    IAM["IAM Policy required"]

    IAM --> P1["bedrock:InvokeModel\nRequired by BedrockLLMClient\n(boto3 invoke_model)"]
    IAM --> P2["bedrock:Converse\nor bedrock:InvokeModel\nRequired by ChatBedrockConverse\n(LangChain)"]

    P1 --> MODELS["Applicable to resources:\narn:aws:bedrock:us-east-1::foundation-model/*\nor specific model ARNs:\n- claude-3-5-sonnet-20241022-v2:0\n- claude-sonnet-4-5-...\n- claude-opus-4-6-..."]
    P2 --> MODELS

    MODELS --> CROSS_REGION["Cross-region inference profiles:\nglobal.anthropic.claude-*\nRequire additional trust for\ncross-region replication"]
```

---

## Token Lifecycle per Bedrock Call

```mermaid
sequenceDiagram
    participant Caller as Service code
    participant Client as Bedrock client
    participant AWS as AWS Bedrock

    Caller->>Client: call with credentials in request
    note over Client: credentials embedded in\nSigV4 signed HTTP headers\n(boto3 handles this automatically)
    Client->>AWS: HTTPS POST with SigV4 auth headers\nX-Amz-Date, X-Amz-Security-Token (if STS),\nAuthorization: AWS4-HMAC-SHA256 ...
    AWS->>AWS: Validate SigV4 signature\nCheck IAM policy for bedrock:InvokeModel
    alt Authorized
        AWS-->>Client: 200 OK + response body
    else Forbidden
        AWS-->>Client: 403 AccessDeniedException
        note over Caller: boto3 raises ClientError\npropagates through timed_llm_call\nRunLog records failure
    else Throttled
        AWS-->>Client: 429 ThrottlingException
        note over Client: botocore retries up to\nBEDROCK_MAX_ATTEMPTS=2\nthen raises
    end
```

---

## Model ID Resolution

```mermaid
flowchart TD
    ENV_VAR["Environment variable\ne.g. BEDROCK_IR_MODEL_ID"]
    DEFAULT["Default constant\nshared/config.py\ne.g. DEFAULT_OPUS_MODEL"]
    ALIAS["_MODEL_ALIASES dict\nbedrock_client.py\ne.g. 'opus' → full ARN"]

    ENV_VAR -->|"if set and non-empty"| RESOLVED["Resolved model ID\ne.g. global.anthropic.claude-opus-4-6-v1"]
    DEFAULT -->|"if env var missing"| RESOLVED
    ALIAS -->|"if caller passes short alias"| RESOLVED

    RESOLVED --> STEP04A["Step 04a: Page Detection\ndetection_model"]
    RESOLVED --> STEP04B["Step 04b: IR Generation\nir_model"]
    RESOLVED --> STEP05["Step 05: React Generation\nreact_model"]
    RESOLVED --> STEP0203["Step 02+03: PRD+Backend\nBACKEND_MODEL_ID\n(non-aliased path)"]
```

---

## Related source files

- [shared/bedrock_client.py](../../shared/bedrock_client.py) — credential resolution + ChatBedrockConverse
- [shared/bedrock_raw_client.py](../../shared/bedrock_raw_client.py) — boto3 direct client
- [shared/config.py](../../shared/config.py) — model IDs + Bedrock region
- [main.py](../../main.py) — .env loading at startup
