# Workload Federation with AWS

Namespace relies on Workload Identity Federation to allow Namespace to interact with different systems, instead of relying on pre-shared keys which can be more easily compromised.

## Accessing Namespace resources from AWS

Identity Federation with AWS allows your AWS-based workloads to identify themselves to Namespace using short-lived secure credentials.

To enable this federation, we rely on [AWS Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html) to establish a [OpenID Connect provider](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html), and then we configure your Namespace workspace to trust that AWS Cognito Identity Pool.

### 1. Create an AWS Cognito Identity Pool

1. Open the **Cognito** console at [https://console.aws.amazon.com/cognito/](https://console.aws.amazon.com/cognito/) and click on **Create identity pool** in the section **Identity pools**.
2. Check the options **Authenticated Access** and **Custom developer provider**.
3. Select an existing IAM role to use with Cognito, or create a new one.

> [!NOTE]
   > AWS requires you to associate an IAM role with the identity pool. The role can have minimal permissions as the pool will be used to access Namespace resources, not AWS resources.
4. Under **Developer provider name** enter `namespace.so`.
5. Pick an arbitrary name for the identity pool and create the identity pool.

AWS will print the ID of the new identity pool. It's of the format `{region}:{guid}`.

### 2. Establish a trust relationship in Namespace

1. Open the [**Dashboard**](https://cloud.namespace.so/workspace/settings) and copy your Workspace ID.
2. Use the [CLI](/content/docs/reference/cli/installation.md) to establish the trust relationship:

```bash
theme={null}
nsc auth trust-aws-cognito-identity-pool \
    --aws_region <region> \
    --identity_pool <guid> \
    --tenant_id <workspace-id>
   ```

### 3. Obtain Namespace credentials from an AWS workload

Using an IAM role with permissions to access the Cognito Identity Pool, you can obtain Namespace credentials as follows:

```bash
theme={null}
nsc auth exchange-aws-cognito-token \
    --aws_region <region> \
    --identity_pool <guid> \
    --tenant_id <workspace-id>
```

This command should succeed with the name of the workspace you've signed in to. It stores a short-lived token that will be used automatically in subsequent calls.

When testing locally, you can select an AWS profile by passing `--aws_profile`.

## Accessing Namespace resources using STS Web Identity

AWS STS Web Identity Federation is a simpler alternative to Cognito that issues short-lived OIDC tokens directly from your AWS account, without requiring an identity pool. Any AWS workload with an IAM role (EC2, Lambda, ECS, etc.) can use this approach.

### 1. Enable outbound web identity federation

This is a one-time setting per AWS account. It enables STS to issue OIDC tokens on behalf of your AWS principals.

```bash
theme={null}
export AWS_PROFILE=<your-aws-profile>

aws --profile "$AWS_PROFILE" iam enable-outbound-web-identity-federation
```

Note the `IssuerIdentifier` in the response. You can retrieve it again at any time:

```bash
theme={null}
aws --profile "$AWS_PROFILE" iam get-outbound-web-identity-federation-info
```

### 2. Grant your IAM role permission to call GetWebIdentityToken

Your workload's IAM role needs permission to obtain tokens. Add an inline policy to the role:

```bash
theme={null}
aws --profile "$AWS_PROFILE" iam put-role-policy \
  --role-name <your-workload-role> \
  --policy-name allow-get-web-identity-token \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Action": "sts:GetWebIdentityToken",
      "Resource": "*"
    }]
  }'
```

### 3. Establish a trust relationship in Namespace

Use the issuer URL and account ID to configure Namespace to trust tokens from your AWS account:

```bash
theme={null}
ISSUER=$(aws --profile "$AWS_PROFILE" iam get-outbound-web-identity-federation-info \
  --query IssuerIdentifier --output text)
ACCOUNT=$(aws --profile "$AWS_PROFILE" sts get-caller-identity --query Account --output text)

nsc auth trust-relationships add \
  --issuer "$ISSUER" \
  --subject-match "arn:aws:iam::${ACCOUNT}:role/<your-workload-role>"
```

To trust any role in the account, use a wildcard:

```bash
theme={null}
  --subject-match "arn:aws:iam::${ACCOUNT}:role/*"
```

### 4. Authenticate from your workload

From within your AWS workload (no additional instance setup required — the AWS CLI picks up credentials from the instance metadata automatically):

```bash
theme={null}
TOKEN=$(aws sts get-web-identity-token \
  --audience https://federation.namespaceapis.com \
  --signing-algorithm ES384 \
  --region us-east-1 \
  --query WebIdentityToken --output text)

nsc auth exchange-oidc-token --token "$TOKEN"
```

`--audience` and `--signing-algorithm` are required by the API. Both `ES384` (ECDSA P-384) and `RS256` are accepted; `ES384` is recommended. `--region` must point to a regional STS endpoint — the global endpoint does not support this call. `--query WebIdentityToken --output text` is a CLI convenience to extract just the token string from the JSON response.

## Accessing AWS resources from Namespace

Identity Federation with AWS allows your Namespace workloads to identify themselves to AWS using short-lived secure credentials.

To enable this federation, create an IAM OIDC identity provider for Namespace federation in the AWS Management Console.

### 1. Create a Namespace OIDC identity provider

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) and in the navigation pane, choose **Identity providers**, and click **Add provider**.
2. Select **OpenID Connect** as a **Provider type** and fill in `https://federation.namespaceapis.com` as the **Provider URL**.

> [!NOTE]
   > The expected thumbprint is `a053375bfe84e8b748782c7cee15827a6af5a405`.
3. For **Audience**, type `sts.amazonaws.com`.
4. Verify the information that you have provided. When you are done choose Add provider.

Note down the ARN of your newly created identity provider. It is of the form `arn:aws:iam::<aws-account-id>:oidc-provider/federation.namespaceapis.com`.

### 2. Create a IAM role for federated access

1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).
2. In the navigation pane, choose **Roles** and click **Create role**.
3. Select the **Custom trust policy** role type, using the following JSON template as the policy:

```json
theme={null}
   {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Principal": {
                "Federated": "<identity-provider-arn>"
            },
            "Condition": {
                "StringLike": {
                    "federation.namespaceapis.com:aud": "sts.amazonaws.com",
                    "federation.namespaceapis.com:sub": "<workspace-id>/*"
                }
            }
        }
    ]
   }
   ```

Replace `<identity-provider-arn>` with the ARN of the new identity provider, and `<workspace-id>` with your complete Namespace workspace identifier (found in the [**Dashboard**](https://cloud.namespace.so/workspace/settings)). The workspace ID includes the `tenant_` prefix; for example, `tenant_123456789ab`.
4. Choose **Next** and add the desired permissions policies for your federated workloads.

### 3. Accessing AWS resources from a Namespace workload

1. Obtain AWS credentials.

```bash
theme={null}
nsc aws assume-role --role_arn <role-arn> --write_env aws.env
   ```

In this command, `<role-arn>` is the ARN of the IAM role created for federated access.
2. Apply the obtained credentials.

```bash
theme={null}
source aws.env
   ```
3. Access AWS resources.

```bash
theme={null}
aws s3 cp test.txt s3://amzn-s3-demo-bucket/test2.txt
   ```

## Pulling private ECR images on instances

When creating an instance through the Compute API, you can pull private images from [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) by having Namespace federate with AWS to obtain a [ECR authorization token](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html) automatically.

The resolved token is used both to pull the instance's own container images and is written into the guest's Docker/nerdctl configuration (`/root/.docker/config.json`), so subsequent `docker pull` and `nerdctl pull` commands from inside the instance authenticate to the same registries.

This builds on the federated IAM role created in [Accessing AWS resources from Namespace](#accessing-aws-resources-from-namespace).

### 1. Grant the IAM role permission to pull from ECR

Attach a policy to the federated role allowing it to obtain an authorization token and pull images:

```bash
theme={null}
aws iam put-role-policy \
  --role-name <your-federated-role> \
  --policy-name allow-ecr-pull \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }]
  }'
```

> [!NOTE]
> `ecr:GetAuthorizationToken` must be granted on `"Resource": "*"`. The remaining actions may be scoped to specific repository ARNs.

### 2. Reference the registry when creating an instance

Set `additional_registries` on the `CreateInstance` request, keyed by your ECR host (`<account-id>.dkr.ecr.<region>.amazonaws.com`). Namespace infers the AWS region from this host, assumes the role via the trust relationship configured above, and uses the resulting token to pull the image:

```json
theme={null}
{
	"containers": [
		{
			"name": "app",
			"image_ref": "<account-id>.dkr.ecr.<region>.amazonaws.com/my-repo:latest"
		}
	],
	"additional_registries": {
		"<account-id>.dkr.ecr.<region>.amazonaws.com": {
			"authentication": {
				"ecr_token_from_aws_federation": {
					"role_arn": "arn:aws:iam::<aws-account-id>:role/<your-federated-role>"
				}
			}
		}
	}
}
```

The registry host key must exactly match the ECR host in `image_ref`. See the [`AdditionalRegistry.Authenticator`](https://buf.build/namespace/cloud/docs/main%3Anamespace.cloud.compute.v1beta#namespace.cloud.compute.v1beta.AdditionalRegistry.Authenticator) reference for all available authentication options.
