# Admin Guide — RBAC & User Management

## How Authentication Works

1. User runs `agent_login_browser` in Claude Code
2. cube-agent opens the browser to `https://cube.edgescaleai-cube.com/auth/login`
3. User enters email + password (Cognito `USER_PASSWORD_AUTH`)
4. On first login, Cognito prompts for a new password (`NEW_PASSWORD_REQUIRED` challenge)
5. cube-cloud validates credentials, extracts the user's Cognito groups from the ID token
6. An API key (`cmcp_...`) is generated, hashed (SHA-256), and stored in DynamoDB
7. The API key is saved locally at `~/.cube-agent/api_key`
8. All subsequent requests use this API key as a Bearer token

### Profile Resolution

Each Cognito group maps to a **profile**. A profile stores Apollo credentials (client ID + secret) in AWS Secrets Manager at `cube-mcp/profiles/<profile-name>`. When a user makes a request, cube-cloud:

1. Validates the API key against DynamoDB
2. Looks up the profile associated with the key
3. Fetches Apollo credentials from Secrets Manager for that profile
4. Uses those credentials for Apollo API calls

## Adding a New User

```bash
aws cognito-idp admin-create-user \
  --user-pool-id <POOL_ID> \
  --username user@example.com \
  --user-attributes Name=email,Value=user@example.com \
  --desired-delivery-mediums EMAIL
```

The user will receive an email with a temporary password. On first login via `agent_login_browser`, they'll be prompted to set a new password.

To find the pool ID:

```bash
aws cognito-idp list-user-pools --max-results 10 --query "UserPools[?starts_with(Name,'cube-mcp')]"
```

## Adding a User to a Group

```bash
aws cognito-idp admin-add-user-to-group \
  --user-pool-id <POOL_ID> \
  --username user@example.com \
  --group-name admin
```

The user's group determines which profile (and therefore which Apollo credentials) they use.

## Creating a New Role / Profile

### 1. Add a Cognito group in `infra/terraform/cognito.tf`

```hcl
resource "aws_cognito_user_group" "engineering" {
  name         = "engineering"
  user_pool_id = aws_cognito_user_pool.main.id
  description  = "Engineering team — maps to engineering profile"
}
```

### 2. Create the Secrets Manager secret

```bash
aws secretsmanager create-secret \
  --name "cube-mcp/profiles/engineering" \
  --secret-string '{"client_id": "<APOLLO_CLIENT_ID>", "client_secret": "<APOLLO_CLIENT_SECRET>"}'
```

Or add it in Terraform (see `infra/terraform/secrets.tf` for the pattern).

### 3. Apply

```bash
cd infra/terraform
terraform apply
```

New users added to the `engineering` group will now use the engineering profile's Apollo credentials.

## Revoking Access

### Disable a user (preserves account)

```bash
aws cognito-idp admin-disable-user \
  --user-pool-id <POOL_ID> \
  --username user@example.com
```

### Delete a user

```bash
aws cognito-idp admin-delete-user \
  --user-pool-id <POOL_ID> \
  --username user@example.com
```

### Revoke API keys

API keys are stored in the `cube-mcp-api-keys` DynamoDB table. To disable a specific key, set `enabled` to `false`:

```bash
# Find keys for a user (by description which contains their email)
aws dynamodb scan \
  --table-name cube-mcp-api-keys \
  --filter-expression "contains(description, :email)" \
  --expression-attribute-values '{":email": {"S": "user@example.com"}}'

# Disable a key
aws dynamodb update-item \
  --table-name cube-mcp-api-keys \
  --key '{"key_hash": {"S": "<HASH>"}}' \
  --update-expression "SET enabled = :f" \
  --expression-attribute-values '{":f": {"BOOL": false}}'
```

## Architecture Reference

| Component | Path |
|-----------|------|
| API key storage (DynamoDB) | `packages/cube-cloud/src/cube_cloud/auth/api_keys.py` |
| Profile → credentials (Secrets Manager) | `packages/cube-cloud/src/cube_cloud/auth/profiles.py` |
| Browser login flow + Cognito auth | `packages/cube-cloud/src/cube_cloud/auth/login_flow.py` |
| Request auth middleware | `packages/cube-cloud/src/cube_cloud/auth/middleware.py` |
| Cognito infrastructure | `infra/terraform/cognito.tf` |
| DynamoDB table | `infra/terraform/dynamodb.tf` |
| Secrets Manager profiles | `infra/terraform/secrets.tf` |
