```html

Authentication Inventory & Migration Readiness: Multi-Account Infrastructure Audit

Over the past session, we completed a comprehensive audit of authentication across JADA's distributed infrastructure: local development on Mac, the Lightsail agent runner, and AWS Lambda chatbots. This post documents the inventory, architectural decisions, and readiness checklist for the planned account migration.

What Was Done

We catalogued three distinct authentication contexts, each with different credential types, lifecycles, and risk profiles. The result is a detailed reference document at /Users/cb/icloud-repos/shared/references/environments.md that serves as the canonical source of truth for credential sourcing, rotation intervals, and account assignments.

  • Mac development environment: Migrating from iOS-billed subscription (metered API key) to web-billed subscription (interactive OAuth in system Keychain)
  • Lightsail jada-agent: Validated existing CLAUDE_CODE_OAUTH_TOKEN and confirmed 1-year validity window under the legacy iOS-billed plan
  • Lambda chatbots: Confirmed Console API key usage (unaffected by subscription tier changes) across four production functions

Technical Details: Three Auth Contexts

Context 1: macOS Interactive Development

The Mac uses OAuth stored in the macOS Keychain under the item named Claude Code-credentials. This is fetched automatically by Claude Code desktop when invoked in interactive mode. The credential includes read/write scopes for projects, file operations, and tool execution. No API key is stored in shell configuration files or environment variables.

# NO API key in interactive shell — uses Keychain OAuth
$ env | grep -i anthropic
# (empty)

# Token refresh happens transparently via Keychain + system auth
$ security find-generic-password -ga "Claude Code-credentials"
# (returns encrypted credential stored in Keychain)

The new web-billed account will also use subscription OAuth in the same Keychain item, maintaining the same interaction pattern. The tier upgrade (from lowest to high-plan) affects only rate limits and feature availability, not auth flow.

Context 2: Lightsail jada-agent (24/7 Agent Runner)

The Lightsail box at 34.239.233.28 runs persistent ticket-automation tasks under the plan-billed Claude Proxy. Authentication is a 1-year CLAUDE_CODE_OAUTH_TOKEN stored in /home/ubuntu/ticket-runner/.env, minted from the old iOS-billed account. This token:

  • Expires: ~12 months from mint date (recorded in the reference doc)
  • Scope: sufficient for project/file/tool access needed by ticket-runner
  • Lifecycle: survives the iOS account downgrade to lowest plan (Lightsail-only use), expires ~April 2027
  • No rotation required during this period; migration path documented for renewal

The token is injected into the environment at agent startup via LaunchAgent or direct process invocation. The reference doc includes a read-only SSH checklist to confirm the token is present and matches expected format:

# SSH validation (read-only check, no modifications)
ssh ubuntu@34.239.233.28 "grep CLAUDE_CODE_OAUTH_TOKEN /home/ubuntu/ticket-runner/.env | wc -c"
# Confirms token is present; length should be ~200 chars for valid JWT structure

ssh ubuntu@34.239.233.28 "cat /home/ubuntu/ticket-runner/.env | head -5"
# Verify no API key bleeding into environment variables

Context 3: Lambda Chatbots

Four production Lambda functions use a shared Console API key for Claude model invocations:

  • dc-chat-api — DragonCorp chat endpoint
  • shipyard-bot — Slack integration
  • shipcaptaincrew — Crew management chatbot
  • tenant-portal-* — Tenant self-service (multiple functions)

The API key is injected via AWS Secrets Manager (or environment variable at function deploy time) and is completely decoupled from subscription tier. The Console API key:

  • Persists across account downgrades (Console is usage-metered, not subscription-gated)
  • Requires no changes during the Mac account migration
  • Is protected by IAM policies restricting Lambda execution role access

Infrastructure & File Layout

The audit produced or updated the following reference documents:

Path Purpose Owner
/Users/cb/icloud-repos/shared/references/environments.md Canonical auth inventory + credential sourcing for all three contexts Local (Mac)
~/icloud-jada-ops/ Working files & credential references (iCloud sync, not git) Local + jada-agent
/home/ubuntu/ticket-runner/.env 1-year OAUTH token + runtime config (Lightsail) Lightsail only
AWS Secrets Manager Console API key + other service credentials (Lambdas) AWS account

Key Decisions & Rationale

Why three separate auth contexts?

Each environment has different runtime requirements and failure domains. The Mac is interactive and user-facing; Lightsail runs headless 24/7; Lambdas are ephemeral and often run in parallel. Mixing credentials (e.g., storing the Lightsail token on Mac, or using Keychain from Lambda) would create hard-to-debug cross-environment issues and increase blast radius if any credential leaks.

Why OAuth token for Lightsail instead of API key?

The ticket-runner agent uses the plan-billed Claude Proxy, which is token-authenticated. OAuth tokens also have narrower scopes (project/file/tool access only) compared to Console API keys, which can be used for any API endpoint. This reduces risk if the token is accidentally logged or committed.

Why keep the old iOS-billed account until April 2027?

The 1-year Lightsail token expires April 2027. Keeping the old account open on the lowest plan costs minimal overhead (~$20/mo) and avoids forcing a token refresh mid-cycle. The account is locked against interactive use (no Keychain credential), so it can only serve as a token issuer. New development work will use the high-tier web-billed account on the Mac.

What's Next

Pre-migration validation:

  • Verify the 1-year OAUTH token on Lightsail is readable and not corrupted
  • Confirm Lightsail can reach Claude endpoints with the stored token (health check script)
  • Audit Lambda environment variables to ensure no API keys are being overwritten by recent deployments
  • Test the new Mac Keychain credential with a dummy project operation (create/read file)

Migration sequence:

  1. Create new web-billed account (pending)
  2. Authenticate to new account on Mac via Claude Code desktop; credential auto-stores in Keychain
  3. Verify jada-ops/ directory remains accessible (iCloud sync, auth-independent)
  4. Downgrade old iOS account to lowest tier; confirm Lightsail token still works
  5. Update reference doc with final auth state and migration completion date

No Lambdas or Lightsail configurations require changes. The ticket-runner will continue using the old account's token; Lambdas will continue using Console API key. Both are unaffected by the Mac account tier shift.

```