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

# Using private Google Artifact Registry images

This guide explains how to use private Google Artifact Registry (GAR) images as Dev Container images when using GCP runners. With runner-native authentication, you can access private GAR repositories without manually managing credentials.

## Prerequisites

Before you begin, ensure you have:

* **GCP runners** deployed and configured for your Ona environments
* **GAR registry** in the same GCP project as your runners (or with appropriate cross-project access)
* **gcloud CLI** installed and authenticated with appropriate permissions to manage IAM policies
* **Runner name and project ID** from your Ona runner configuration

## Setting up Google Artifact Registry Access

### Step 1: Create Container Registry Secret

1. Navigate to **Project → Secrets → New Secret** in your Ona dashboard

2. Select **Container Registry Basic Auth** from the type dropdown

3. For the **Registry hostname**, enter your GAR registry hostname in the format: `[region]-docker.pkg.dev`

   Examples:

   * `us-central1-docker.pkg.dev` (for US Central region)
   * `europe-west1-docker.pkg.dev` (for Europe West region)
   * `asia-southeast1-docker.pkg.dev` (for Asia Southeast region)

4. When you enter a GAR registry hostname, the username and password fields will automatically be filled with `runner-native` to indicate that native runner authentication will be used

5. Click **Add**

<Note>
  **Runner-native Authentication**: When you enter a GAR hostname, Ona automatically detects this as a supported registry and enables runner-native authentication, eliminating the need for manual credential management.
</Note>

### Step 2: Configure Service Account Permissions

Your GCP runner creates an environment VM service account that needs access to your GAR repositories.

#### Identify Your Environment Service Account

Your environment service account follows this naming pattern:

```
{RUNNER_NAME}-env-vm@{PROJECT_ID}.iam.gserviceaccount.com
```

For example, if your runner is named `gcp-runner-01` in project `my-project-123`, the service account would be:

```
gcp-runner-01-env-vm@my-project-123.iam.gserviceaccount.com
```

#### Grant Repository Access (Recommended)

Use the `gcloud` command to grant access to specific repositories:

```bash theme={null}
# Set your configuration variables
PROJECT_ID="your-project-id"
RUNNER_NAME="your-runner-name"
REGION="your-region"
REPO_NAME="your-repository-name"

# The environment VM service account (automatically created by your runner)
ENVIRONMENT_VM_SERVICE_ACCOUNT="${RUNNER_NAME}-env-vm@${PROJECT_ID}.iam.gserviceaccount.com"

# Grant repository access
gcloud artifacts repositories add-iam-policy-binding $REPO_NAME \
    --location=$REGION \
    --member="serviceAccount:${ENVIRONMENT_VM_SERVICE_ACCOUNT}" \
    --role="roles/artifactregistry.reader"
```

#### Alternative: Project-level Access

For broader access, you can grant project-level permissions:

```bash theme={null}
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${ENVIRONMENT_VM_SERVICE_ACCOUNT}" \
    --role="roles/artifactregistry.reader"
```

### Step 3: Configure Your Dev Container

Update your `.devcontainer/devcontainer.json` to use your private GAR image:

```json theme={null}
{
    "name": "My Dev Container",
    "image": "us-central1-docker.pkg.dev/my-project-123/my-repo/my-image:latest",
    "features": {
        // Your features here
    }
}
```

## Required IAM roles

The minimum required role for accessing GAR repositories is:

```
roles/artifactregistry.reader
```

For more granular control, you can create a custom role with these specific permissions:

```
artifactregistry.repositories.downloadArtifacts
artifactregistry.repositories.get
artifactregistry.repositories.list
```

## Verification

To verify the permissions are correctly configured:

### Check Repository-level Permissions

```bash theme={null}
gcloud artifacts repositories get-iam-policy $REPO_NAME --location=$REGION
```

### Check Project-level Permissions

```bash theme={null}
gcloud projects get-iam-policy $PROJECT_ID \
    --flatten="bindings[].members" \
    --format="table(bindings.role)" \
    --filter="bindings.members:${ENVIRONMENT_VM_SERVICE_ACCOUNT}"
```

### Verify Service Account Exists

```bash theme={null}
# List all service accounts in your project
gcloud iam service-accounts list --project=$PROJECT_ID

# Look for accounts matching the pattern: {RUNNER_NAME}-env-vm@{PROJECT_ID}.iam.gserviceaccount.com
```

## Limitations

* **GCP runners only**: GAR runner-native registry support is only available for GCP runners
* **Same project recommended**: Your GCP runners and GAR registry should be in the same project for simplest configuration
* **Environment recreation required**: Existing environments must be recreated to apply changes to GAR permissions
* **No automatic docker login**: Unlike basic auth registries, GAR doesn't automatically log you into the registry from within the environment. Use [gcloud auth](https://cloud.google.com/artifact-registry/docs/docker/authentication) or [Ona OIDC](/ona/configuration/oidc) for additional registry access from within your environment

## Next steps

* Learn more about [GCP runner setup](/ona/runners/gcp/setup)
* Explore [container registry secrets](/ona/configuration/secrets/container-registry-secret) for other registry types
* Configure [OIDC authentication](/ona/configuration/oidc) for additional cloud service access

## Troubleshooting

<Accordion title="Image Pull Failures">
  If you're experiencing image pull failures, verify:

  1. **Service account name is correct**:
     ```bash theme={null}
     # List all service accounts in your project
     gcloud iam service-accounts list --project=$PROJECT_ID
     ```

  2. **IAM permissions are correctly applied**:
     ```bash theme={null}
     # Check repository-level permissions
     gcloud artifacts repositories get-iam-policy $REPO_NAME --location=$REGION
     ```

  3. **Repository exists and is accessible**:
     ```bash theme={null}
     # List repositories in the region
     gcloud artifacts repositories list --location=$REGION
     ```
</Accordion>

<Accordion title="Authentication Errors">
  If you see authentication errors in your environment logs:

  * Ensure the GAR hostname format is correct: `[region]-docker.pkg.dev`
  * Verify that your runner and registry are in the same project or have cross-project access configured
  * Check that the service account has the minimum required role: `roles/artifactregistry.reader`
  * Confirm the service account name matches the expected pattern
</Accordion>

<Accordion title="Common Error Messages">
  **"Failed to pull image"**

  * Check that the image exists in the specified repository
  * Verify the image tag is correct
  * Ensure the service account has pull permissions

  **"Authentication required"**

  * Confirm the container registry secret is properly configured
  * Verify the service account has the correct IAM roles
  * Check that the GAR hostname matches your registry region
</Accordion>
