diff --git a/content/api/overview.md b/content/api/overview.md index 50187fb..254f615 100644 --- a/content/api/overview.md +++ b/content/api/overview.md @@ -33,6 +33,24 @@ right choice for CI and back-end services): Authorization: Basic base64(:) ``` +**Google Cloud service account** — pass a Google Cloud SA **access token** as the +bearer token, instead of issuing a deploys.app key: + +```http +Authorization: Bearer +``` + +The token must include the `https://www.googleapis.com/auth/userinfo.email` scope +(deploys.app identifies the caller by the token's email), and the service +account's email (`@.iam.gserviceaccount.com`) must be granted the +permissions you need via [Roles](/access/roles/). Mint one with `gcloud auth +print-access-token --scopes=https://www.googleapis.com/auth/userinfo.email`, or in +GitHub Actions with `google-github-actions/auth` (`token_format: access_token`). +It's the same identity the [container +registry](/registry/overview/#using-a-google-cloud-service-account) accepts — +useful when you already run in Google Cloud and don't want to manage a separate +deploys.app key. Note these tokens are short-lived (about an hour). + Unauthenticated calls and calls with a bad token return **401 Unauthorized**. Calls authenticated but missing a [permission](/access/roles/) return a **200 OK** response with `{ "ok": false, "error": { "message": "api: forbidden" } }` — diff --git a/content/registry/overview.md b/content/registry/overview.md index 9e4615b..e75adf0 100644 --- a/content/registry/overview.md +++ b/content/registry/overview.md @@ -35,6 +35,49 @@ The username for service accounts is the account email; the password is the key. Generate one from [Service accounts → Keys](/access/service-accounts/) in the console. +### Using a Google Cloud service account + +You can also authenticate with a **Google Cloud service account** instead of a +deploys.app key — handy when you already run in Google Cloud or in GitHub Actions +with a Google credential. The username is the literal `oauth2accesstoken` and the +password is a short-lived **access token** for the service account: + +```bash +docker login registry.deploys.app \ + -u oauth2accesstoken \ + -p "$(gcloud auth print-access-token \ + --scopes=https://www.googleapis.com/auth/userinfo.email)" +``` + +Two things are required: + +- **The access token must carry the `https://www.googleapis.com/auth/userinfo.email` + scope.** The registry identifies the caller by the token's email, so a token + without that scope (for example the default `cloud-platform`-only token) is + rejected with `unauthorized: authentication required`. +- **The service account's email must be granted registry access on the project.** + Add `@.iam.gserviceaccount.com` as a member of a role that holds + `registry.push` (to push) and/or `registry.pull` (to pull) under + [Roles](/access/roles/), exactly as you would any other member. + +In **GitHub Actions** with `google-github-actions/auth`, request the email scope +alongside any others you need, then log in with the access token: + +```yaml +- uses: google-github-actions/auth@v3 + id: auth + with: + credentials_json: ${{ secrets.GOOGLE_CREDENTIALS }} + token_format: access_token + # keep cloud-platform too if the same token also pushes to Artifact Registry + access_token_scopes: https://www.googleapis.com/auth/userinfo.email +- uses: docker/login-action@v4 + with: + registry: registry.deploys.app + username: oauth2accesstoken + password: ${{ steps.auth.outputs.access_token }} +``` + ## Pushing an image The repository name is `/` — the project is your project ID,