> ## Documentation Index
> Fetch the complete documentation index at: https://docs.augmentcode.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Import images from private registry

> Use a private AWS ECR image as Cosmos environment base image using static AWS IAM credentials or a AWS IAM role with a OIDC identity provider like Okta.

# Introduction

You can use a container image from a private registry as the base image for a [Cosmos cloud environment](/cosmos/environments/cloud.md). Store a registry credential in Cosmos, then select it when creating the environment. Cosmos uses the credential to authenticate and pull the image during the build; it is not automatically installed as an environment variable inside your session.

This guide covers two ways to authenticate to AWS ECR (Elastic Container Registry):

* **Static IAM credentials:** an AWS access key ID and secret.
* **OIDC (recommended):** credentials for your identity provider that Cosmos exchanges for temporary AWS credentials through an IAM role. This avoids storing long-lived AWS IAM access keys, but still requires an identity-provider client secret

> [!NOTE]
>
> Cosmos plans to eventually add support for private key for the OIDC client - stay tuned.

# Before you begin

* Have an image in a **private ECR repository**, with the dependencies required by Cosmos, including `bash` and `git`.
* Copy the full image URI from ECR, including an **existing tag**, for example `123456789012.dkr.ecr.us-east-1.amazonaws.com/my-environment:24.04`. Replace the example account, region, repository, and tag with your own values. Do not assume your repository has a `latest` tag.
* Have permission to configure IAM and ECR, create a registry credential in Cosmos, and create a cloud environment.
* Use the same AWS region in the registry credential and the image URI.
* If using **OIDC authentication**, have permission to configure an OIDC-compliant identity provider. This guide uses [**Okta**](https://okta.com) as an example, with a custom authorization server and a machine-to-machine (M2M) OIDC client using the **client credentials** grant type.

> [!NOTE]
>
> The OIDC sign-in option must be enabled for your organization. If **IAM role (OIDC client credentials)** is not shown, contact your Augment Solutions Architect. This guide uses **cloud** environments; ECR support for [self-hosted k8s environments](/cosmos/guides/self-hosted-k8s.md) depends on your organization's configuration.

# Import from AWS ECR using static IAM credentials

## 1. Grant read-only access to the repository

Create a dedicated IAM user for image pulls, or use an existing identity approved by your AWS administrator. Attach an IAM permissions policy with the following access, replacing the repository ARN with your own:

```json wrap theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ecr:GetAuthorizationToken",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchCheckLayerAvailability"
      ],
      "Resource": "arn:aws:ecr:us-east-1:123456789012:repository/my-environment"
    }
  ]
}
```

`ecr:GetAuthorizationToken` requires `Resource: "*"`. Restrict the image and layer permissions to the repositories you need; push or administrator permissions are not required. For a cross-account repository, its repository policy must also allow the IAM identity to pull images. See [AWS ECR repository policies](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html).

Create an access key for this IAM user and store it securely. Use the AWS access key pair, not a Docker username/password or a manually generated ECR login token.

## 2. Save the registry credential in Cosmos

Open [cosmos.augmentcode.com](https://cosmos.augmentcode.com) → **Settings → Registry Credentials**, then select **Add a credential**.

| Field | Value |
| - | - |
| **Name** | A descriptive name, such as `ecr-image-pull`. Use letters, numbers, underscores, or hyphens. |
| **Registry type** | **AWS ECR** |
| **Sign-in method**, if shown | **Access keys** |
| **Access key ID** | Your IAM user's access key ID. |
| **Secret access key** | The matching secret access key, entered directly in the secure form. |
| **Region** | The region containing your ECR image, such as `us-east-1`. |

Choose the available personal or shared access and Space settings so the intended environment creator can use the credential, then select **Create credential**.

> [!NOTE]
>
> Saving a registry credential stores its configuration. It does **not** contact ECR or try to fetch `latest` (or any other tag), and does not prove that the credential can pull an image.

Keep the key valid for future image builds, and rotate it according to your organization's policy. Continue to [Create the environment from the private image](#create-the-environment-from-the-private-image).

# Import from AWS ECR using OIDC (recommended)

With this method, Cosmos:

1. Requests an OAuth **access token** from your identity provider using the `client_credentials` grant.
2. Passes that access token to AWS STS `AssumeRoleWithWebIdentity` to obtain temporary IAM role credentials.
3. Uses those credentials to request an ECR authorization token and pull the image.

Cosmos uses the token response's `access_token`, not an `id_token`. Your identity provider must issue a signed JWT access token that AWS STS accepts for web-identity federation. An opaque access token is not sufficient.

This guide uses [**Okta**](https://okta.com) as an example of identity provider.

## 1. Configure your identity provider (Okta)

Configure three separate objects in Okta: an **API Services application** (the machine-to-machine client), a **custom authorization server** (the token issuer), and an **access policy with a rule** that allows this client to request tokens. Creating the application alone does not authorize it to use the server.

> [!NOTE]
>
> Your Okta organization must support custom authorization servers and the Client Credentials grant. API Access Management is required for custom authorization servers in production, and Client Credentials availability can depend on your Okta subscription. If the options below are missing, ask your Okta administrator to confirm availability. See [Okta's authorization-server guide](https://developer.okta.com/docs/guides/customize-authz-server/main/) and [access-policy requirements](https://help.okta.com/en-us/Content/Topics/Security/api-config-access-policies.htm).

### 1.1. Create the machine-to-machine application

1. Sign in to your organization's **Okta Admin Console** and open the **Applications** page.
2. Select **Create App Integration**. If the new integration wizard does not offer **API Services**, select **Classic experience**, as described in [Okta's Client Credentials setup guide](https://developer.okta.com/docs/guides/implement-grant-type/clientcreds/main/#set-up-your-app).
3. Choose **API Services** as the sign-in method, then select **Next**. Do not choose a browser-based web or single-page application: this flow has no interactive user sign-in or redirect URI.
4. Enter an application name, such as `Cosmos M2M - AWS ECR`, then select **Save**.
5. On the application's **General** tab, locate **Client Credentials**. Record the **Client ID** and store the **Client secret** securely for entry into Cosmos later. If grant types are editable, ensure **Client Credentials** is enabled.
6. Use **Client secret** authentication with the token-endpoint method **`client_secret_basic`**. Cosmos sends the client ID and secret in an HTTP Basic header, not in the request body. Do not configure this application to require a private-key JWT instead. See [Okta's client authentication methods](https://developer.okta.com/docs/api/openapi/okta-oauth/guides/client-auth).

You M2M app should look like this:

![Screenshot 2026 10 22 At 4 49 32 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-4.49.32-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=14a9076824ddc85d1b27765ad879a2f6)

You do not need to assign end users or grant Okta management API scopes for this image-pull flow. The next steps authorize this application against your custom server.

### 1.2. Create a custom authorization server

1. In the Okta Admin Console, open **Security → API → Authorization Servers**.
2. Select **Add Authorization Server**.
3. Enter a **Name**, such as `Cosmos AWS ECR`, and a **Description** explaining that the server issues tokens for private ECR image pulls.
4. Set **Audience** to `aws-ecr` for this guide's example. This is the audience issued in the access token; keep it consistent with the AWS OIDC provider and IAM trust policy configured below. If your organization requires a different audience, replace the example consistently throughout the setup.
5. Select **Save**. On the server's **Settings** tab, record its **Issuer** URL, including the `/oauth2/<authorization-server-id>` path.
6. Open the server's **Metadata URI**, or its issuer URL followed by `/.well-known/openid-configuration`. Record the returned `issuer` and `token_endpoint` values. Use this exact HTTPS token endpoint in Cosmos; do not use a URL that redirects.

> [!WARNING]
>
> Use a **custom** authorization server, not the org authorization server at the bare Okta domain.

Your AuthZ server Settings tab should look like this:

![Screenshot 2026 10 22 At 4 55 02 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-4.55.02-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=c4dba8656613e761c3d2a02748ac3350)

### 1.3. Add the custom scope

1. On your custom authorization server, select **Scopes → Add Scope**.
2. Set **Name** to `fetch-image`. Enter a display phrase and description, such as `Pull private ECR images`.
3. Leave **Require user consent for this scope** unselected: client credentials requests have no user to provide consent.
4. Leave **Set as a default scope** unselected for this example; you will explicitly set `fetch-image` in Cosmos.
5. Select **Create**.

Do not request `openid`, `profile`, or other user-oriented OpenID scopes for this machine-to-machine flow. The custom scope lets Okta authorize token issuance; the IAM permissions policy, not this scope, grants access to ECR repositories.

Your AuthZ server Scopes tab should look like this:

![Screenshot 2026 10 22 At 4 58 49 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-4.58.49-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=cea3418bfc45416001fe174d7a72ddfe)

### 1.4. Create the access policy and rule

1. On the same authorization server, select **Access Policies → Add Policy**.
2. Enter a **Name**, such as `Cosmos ECR client`, and a description.
3. Under **Assign to**, choose **The following clients** and select the `Cosmos M2M - AWS ECR` application created above. Do not choose **All clients** for this dedicated policy.
4. Select **Create Policy**. Open the new policy and select **Add Rule**.
5. Enter a **Rule Name**, such as `Allow client credentials`, and configure:
   | Rule setting | Value |
   | - | - |
   | **IF Grant type is** | **Client Credentials** only. Expand **Advanced** if needed to find the option. |
   | **AND User is**, if shown | **No user**. A rule that requires an assigned user does not match a client credentials request. |
   | **AND Scopes requested** | Select the specific scope `fetch-image`, rather than allowing any scope. |
   | **Access token lifetime** | A short lifetime approved by your organization, for example **1 hour**. |
6. Select **Create Rule**. Confirm that both the policy and its rule are active.
7. Review policy and rule order. Okta evaluates them in priority order and uses the first matching policy and rule.

Your AuthZ server Access Policies tab should look like:

![Screenshot 2026 10 22 At 5 05 24 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.05.24-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=352ef0ac9527adf1605f51746c1d267d)

The corresponding rule should look like:

![Screenshot 2026 10 22 At 5 07 52 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.07.52-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=09c434cee97302c53856b7703971173c)

### 1.5. Test the configuration with Token Preview

Use Okta's **Token Preview** to check the application's grant type, scope, and expected access-token claims before making a real token request.

1. On the same authorization server → Click on the **Token Preview** tab.

In **Request Properties**, configure:

| Field | Value |
| - | - |
| **OAuth/OIDC client** | Select **Cosmos M2M - AWS ECR**. Type the application name to find it. |
| **Grant type** | **Client Credentials**. |
| **Scopes** | Select **fetch-image**. |

1. Select **Preview Token** and inspect the **Access Token** result, not an ID token.
2. Confirm that the preview succeeds, `iss` matches your custom authorization server's issuer, `aud` is `aws-ecr`, and `scp` includes `fetch-image`. Inspect `sub` and whether `azp` is present; verify their actual issued values in the next step before configuring AWS.

Your token preview should look like:

![Screenshot 2026 10 22 At 5 10 09 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.10.09-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=76c97033892cf86f2f5e208a34ed506e)

If the preview reports an error, check that the client and scope belong to this setup, the policy is assigned to **Cosmos M2M - AWS ECR**, and an active rule permits **Client Credentials** with **fetch-image**. Review policy and rule priority if the expected rule does not match.

### 1.6. Record the values and verify token issuance

The following are example values, not values to copy unchanged:

<table>
  <colgroup>
    <col width="247" />

    <col width="442" />
  </colgroup>

  <thead>
    <tr>
      <th>Setting</th>
      <th>Example or source</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Issuer URL</td>
      <td>`https://example.okta.com/oauth2/authorization-server-id`; copy your server's actual issuer.</td>
    </tr>

    <tr>
      <td>Token URL</td>
      <td>`https://example.okta.com/oauth2/authorization-server-id/v1/token`; copy `token_endpoint` from your server's metadata.</td>
    </tr>

    <tr>
      <td>Client ID and client secret</td>
      <td>From the **Client Credentials** section on the API Services application's **General** tab. Store the secret securely.</td>
    </tr>

    <tr>
      <td>Authorization-server audience</td>
      <td>`aws-ecr`, configured on the server.</td>
    </tr>

    <tr>
      <td>Custom scope</td>
      <td>`fetch-image`, configured on the server and allowed by the policy rule.</td>
    </tr>
  </tbody>
</table>

Before configuring AWS, run this curl request in a trusted local terminal. Replace the example URL with your authorization server's `token_endpoint` and `YOUR_CLIENT_ID` with the client ID of **Cosmos M2M - AWS ECR**:

```bash wrap theme={null}
curl --request POST \
  --url 'https://example.okta.com/oauth2/authorization-server-id/v1/token' \
  --basic --user 'YOUR_CLIENT_ID' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=fetch-image'
```

When curl prompts for a password, enter the application's **client secret**. You should get this response:

```json wrap theme={null}
{
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "XXXX.XXXX.XXXX",
  "scope": "fetch-image"
}
```

## 2. Register the issuer in AWS IAM

In the AWS console, open **IAM → Identity providers → Add provider**, then choose **OpenID Connect**.

* Set **Provider URL** to the token's exact `iss` value, including any authorization-server path. For the Okta example, use `https://example.okta.com/oauth2/authorization-server-id`, not just `https://example.okta.com` and not the `/v1/token` URL.
* Set the AWS provider's **Audience** to the token's `aud` value. **If the token includes `azp`, AWS uses that value instead** for this check.
* Create the provider in the same AWS account as the IAM role you will configure next.

Your identity provider should look like this:

![Screenshot 2026 10 22 At 5 23 58 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.23.58-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=1bbeac0cdff80e3b8f24bd04473f2a23)

![Screenshot 2026 10 22 At 5 25 00 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.25.00-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=1c918897cda9a1b1158a93ee247a3f8e)

## 3. Create the IAM role and trust policy

Create an IAM role, such as `OktaECRPullRole`. Attach the same repository-scoped **ECR permissions policy** shown in the [static IAM credentials section](#1-grant-read-only-access-to-the-repository).

Separately, configure the role's **trust policy** to allow `sts:AssumeRoleWithWebIdentity` from your IAM OIDC provider. Restrict it to the expected audience and application subject. For the example issuer above, a trust policy is:

```json wrap theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/example.okta.com/oauth2/authorization-server-id"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "example.okta.com/oauth2/authorization-server-id:aud": "aws-ecr",
          "example.okta.com/oauth2/authorization-server-id:sub": "EXPECTED_APPLICATION_SUBJECT"
        }
      }
    }
  ]
}
```

Replace the account ID, issuer host/path, audience, and subject with your own values. The provider ARN and condition-key prefixes include the issuer path but omit `https://`.

This example assumes the token has **no `azp` claim**. If it has one, the `:aud` condition must match `azp`; AWS exposes the original `aud` as `:oaud`. Review [AWS's OIDC claim-to-condition mapping](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif) before adapting the policy.

The trust policy controls **who can assume the role**; the attached permissions policy controls **which ECR images the role can pull**. Both are required.

## 4. Save the OIDC registry credential in Cosmos

Open [cosmos.augmentcode.com](https://cosmos.augmentcode.com) → **Settings → Registry Credentials → Add a credential** and fill in:

<table>
  <colgroup>
    <col width="140" />

    <col width="511" />
  </colgroup>

  <thead>
    <tr>
      <th>Field</th>
      <th>Value</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>**Name**</td>
      <td>A descriptive name, such as `aws-ecr-oidc-pull`.</td>
    </tr>

    <tr>
      <td>**Registry type**</td>
      <td>**AWS ECR**</td>
    </tr>

    <tr>
      <td>**Sign-in method**</td>
      <td>**IAM role (OIDC client credentials)**</td>
    </tr>

    <tr>
      <td>**Role ARN**</td>
      <td>Your role ARN, for example `arn:aws:iam::123456789012:role/OktaECRPullRole`.</td>
    </tr>

    <tr>
      <td>**Token URL**</td>
      <td>Your identity provider's HTTPS token endpoint, for example `https://example.okta.com/oauth2/authorization-server-id/v1/token`</td>
    </tr>

    <tr>
      <td>**Client ID**</td>
      <td>The machine-to-machine application's client ID.</td>
    </tr>

    <tr>
      <td>**Client secret**</td>
      <td>The application's secret.</td>
    </tr>

    <tr>
      <td>**Audience**</td>
      <td>Keep blank. Set only if your provider requires an `audience` parameter in the token request.</td>
    </tr>

    <tr>
      <td>**Scope**</td>
      <td>The scope your provider requires; for the example above, `fetch-image`.</td>
    </tr>

    <tr>
      <td>**Region**</td>
      <td>The region containing your ECR image, such as `us-east-1`.</td>
    </tr>
  </tbody>
</table>

Your Add registry credential view should look like:

![Screenshot 2026 10 22 At 5 43 14 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.43.14-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=6694ad1748b99b905067e6c2c576614f)

Choose the appropriate access and Space settings, then select **Create credential**. Do not enter static AWS access keys for this method.

> [!NOTE]
>
> **The Cosmos Audience field and the JWT audience are different settings.** Cosmos only sends an `audience` request parameter when this field is filled in. Leaving it blank does not mean the token has no `aud` claim. For the Okta custom-authorization-server example, configure `aws-ecr` on the authorization server and leave the Cosmos field blank if no request parameter is required. AWS must still accept the audience actually issued in the token, accounting for `azp` when present.

# Create the environment from the private image

After saving either a static IAM or OIDC registry credential, use these steps to create the environment:

1. Open [cosmos.augmentcode.com](https://cosmos.augmentcode.com) → **Settings → Environments**.
2. Select **Create an environment → Augment Cloud**.
3. Enter an environment name.
4. Under **Base image**, select **Private registry**.
5. In **Registry URL**, enter the complete ECR image URI, including its existing tag. Do not add `https://`.
6. In **Registry credential**, select the static IAM or OIDC credential you created.
7. Select **Create Environment** and wait for the build to finish successfully before starting a session.

Your Create Environment view should look like:

![Screenshot 2026 10 22 At 5 58 06 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-5.58.06-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=59812187b7f83b08bc2d543b033966b1)

The environment will build:

![Screenshot 2026 10 22 At 6 01 18 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-6.01.18-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=9a496342af410b8b0d497c049713990a)

You should see this when created:

![Screenshot 2026 10 22 At 6 02 48 PM](https://mintcdn.com/augment-mtje7p526w/QpTEtdVcZkrEalR1/images/Screenshot-2026-10-22-at-6.02.48-PM.png?fit=max\&auto=format\&n=QpTEtdVcZkrEalR1\&q=85\&s=8f81afa11cc09fedea4879cf044039a1)

The build is the check that Cosmos can authenticate, retrieve the selected image, and prepare the environment.

A successful standalone IdP → STS → ECR test confirms authentication and image access, but does **not** verify a Cosmos environment build or that the image contains the required tools.

Congrats, you've configured a cloud environment pulling a custom image from ECR! 🎉

## Troubleshooting

| Symptom | What to check |
| - | - |
| OIDC sign-in method is missing | The option must be enabled for your Augment tenant. Contact your Augment Solutions Architect. |
| Token request fails | Confirm the client ID/secret, HTTP Basic authentication, allowed client-credentials grant, scope, and any provider-required audience parameter. Use the final publicly reachable HTTPS token URL; redirects and private-network endpoints are not supported. |
| AWS reports no matching OIDC provider or an invalid token/audience | Match the complete issuer URL, including its path. Check AWS access to discovery/signing keys and the provider's accepted audience; account for `azp`. |
| STS returns access denied | Check the role ARN and trust policy's provider, `sts:AssumeRoleWithWebIdentity` action, and exact audience/subject conditions. Do not substitute unsupported custom claims such as `scp`. |
| ECR denies authentication or image access | Check `ecr:GetAuthorizationToken`, repository-scoped pull permissions, region, and any cross-account repository policy. |
| Pull returns `MANIFEST_UNKNOWN` or image/tag not found | Confirm the repository and explicit tag exist. Successful authentication does not create a missing `latest` tag. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.