# AWS access

> Connect an IAM role to your workspace once, and every box gets an AWS profile that assumes it with a short-lived identity token. No access keys on the box, no sign-in that expires.

URL: https://prized.dev/docs/aws

## How it works [#how-it-works]

Prized is an OpenID Connect identity provider for your boxes. A box holds a signed identity token that names its workspace and refreshes on its own; the AWS CLI and SDKs exchange it for temporary credentials by calling `AssumeRoleWithWebIdentity` against a role in your account. The same pattern GitHub Actions and Kubernetes use for keyless access, and the same trust boundary: your administrator decides which role the workspace may assume and what it may do.

```bash title="you@box ~"
aws sts get-caller-identity --profile acme
# {
#     "Arn": "arn:aws:sts::123456789012:assumed-role/prized-devbox/you@acme.com"
# }
```

Nothing to install and nothing to log in to. `~/.aws/config` on every box in the workspace carries a `[profile <name>]` per connected role; `aws`, `terraform`, `kubectl` after `aws eks update-kubeconfig`, and every SDK read it. Credentials are minted per call and last an hour; the token behind them is renewed well before it expires, so a box that has been running for a month still works.

## Connect an AWS account [#connect-an-aws-account]

**Dashboard → Workspace**, the **Cloud federation** card, owner only. Click **Connect** on the Amazon Web Services row. The AWS console opens on a pre-filled CloudFormation stack; whoever is signed into the right account reviews the role name and the permission policies, ticks the IAM acknowledgement and clicks **Create stack**. A minute or two later the role appears on the card as **Connected**, with nothing typed or pasted. If the AWS administrator is not you, **Copy** the link and send it to them: it is good for one hour, works once, and needs no Prized account.

The stack creates the identity provider, a role named `prized-devbox` with `ReadOnlyAccess` attached (both changeable before creating), and a small one-shot function that reports the role to Prized and then does nothing. A second workspace in the same AWS account sets **CreateIdentityProvider** to `No`, since an account holds one provider per URL. If the stack fails, its events name the reason (an expired link, a workspace that already has ten roles); make a new link and create it again.

## Connect a role you created yourself [#connect-a-role-you-created-yourself]

An administrator who applies IAM changes through their own tooling can skip the stack: create the identity provider (URL `https://prized.dev`, audience `sts.amazonaws.com`) and a role whose trust policy allows `sts:AssumeRoleWithWebIdentity` from it with `prized.dev:aud` = `sts.amazonaws.com` and `prized.dev:sub` like `workspace:<your workspace id>:*`, then connect the role's ARN with the [API](https://prized.dev/docs/api#cloud-federation). Prized checks it against AWS at once and shows the answer on the row: **Connected**, or **Check failed** with what to fix. **Verify** repeats the check; **Remove** ends it for every box.

A workspace can connect up to 10 roles, for a read-only and a break-glass one for instance; each becomes its own profile. Members see the connected roles and profile names and cannot change them; a contractor's role does not include cloud federation.

## What AWS sees [#what-aws-sees]

Every assumption carries the box's subject, `workspace:<id>:box:<id>`, and a role session name that is the box owner's email address, so CloudTrail reads `assumed-role/prized-devbox/you@acme.com` per person even though nobody signed in. Permissions are the role's; scope them there as you would for any federated identity. Restrict the trust policy further with a `sub` condition on a specific box id if a role should reach one machine only.

## On the box [#on-the-box]

| What               | Where                                                                                                                                                          |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The profiles       | A fenced block in `~/.aws/config` that Prized keeps current; everything outside the block, including profiles `prized setup` copied from your laptop, is yours |
| The identity token | `~/.prized/aws-token`, readable by your user only, renewed by the box                                                                                          |
| Credentials        | Minted by the CLI or SDK per call from the token, cached the way they always are (`~/.aws/cli/cache`)                                                          |

Removing a role, or the workspace closing, removes its profile and the token from every box within a few minutes. Boxes marked [safe for third parties](https://prized.dev/docs/environments#safe-for-third-parties), which includes every contractor's box, and boxes from an environment with **Secret mounts** switched off receive no profile and no token: the same rule as workspace secrets.

## Troubleshooting [#troubleshooting]

| Symptom                                                                                                | Cause and fix                                                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The stack fails with `Prized refused the connect (connect_link_expired)` or `(connect_link_cancelled)` | The link outlived its hour, or was cancelled or replaced in Prized. Make a new link from the card and create the stack again.                                                                                                                                                           |
| The stack succeeds but the row says `Check failed`                                                     | AWS had not finished propagating the new role when Prized checked. Click **Verify**.                                                                                                                                                                                                    |
| `Check failed: Account … has no identity provider for https://prized.dev`                              | The provider was not created, or under a different URL. Create it with the exact URL and audience above.                                                                                                                                                                                |
| `Check failed: AWS refused the role: its trust policy does not admit this workspace`                   | The `sub` condition or the audience does not match. Delete the stack and create it again from a fresh link, or fix the trust policy on the role.                                                                                                                                        |
| `Unable to locate credentials` on the box                                                              | The profile is not selected: pass `--profile <name>` or `export AWS_PROFILE=<name>`.                                                                                                                                                                                                    |
| The profile works on one box and not another                                                           | The other box has not polled yet; wait a few minutes. A box marked safe for third parties never gets the profile. If `~/.aws` or `~/.aws/config` on that box is a symlink (a dotfiles repo, a synced folder), Prized leaves it alone and writes nothing; move the real file into place. |
| `RegionDisabled`                                                                                       | Your account has the global STS endpoint disabled. Enable it in IAM account settings, or set `sts_regional_endpoints = regional` and a `region` on the profile.                                                                                                                         |
