A shell script to manually authenticate and fetch the manifest for a private container image from the GitHub Container Registry (GHCR). This script is useful for debugging authentication issues with GHCR or for programmatically inspecting image metadata (like layers and digests) without needing to perform a full docker pull. How It Works It performs the standard two-step authentication flow required by Docker V2-compatible registries: Request a Bearer Token: It first authenticates against the GHCR token endpoint (https://ghcr.io/token) using a GitHub Personal Access Token (PAT). It requests a temporary, scoped token with pull access to the specific repository. Fetch the Manifest: It then uses the temporary bearer token to make an authenticated GET request to the registry's manifest API endpoint to retrieve the image manifest.
1#!/bin/bash
2
3# === CONFIGURATION ===
4# The GitHub user or organization that owns the package.
5OWNER="coding-cloud"
6# The name of the container image package.
7IMAGE_NAME="my-awesome-app"
8# The tag of the image you want to inspect.
9TAG="latest"
10# The Personal Access Token (PAT) with `read:packages` scope.
11GH_PAT=""
12# The username for authentication. Defaults to the OWNER.
13AUTH_USER="${OWNER}"
14# =====================
15
16
17# --- SCRIPT LOGIC ---
18
19if [ -z "$GH_PAT" ]; then
20 echo "Error: GH_PAT variable is not set. Please edit the script to add your token." >&2
21 exit 1
22fi
23
24SCOPE="repository:${OWNER}/${IMAGE_NAME}:pull"
25TOKEN_URL="https://ghcr.io/token?service=ghcr.io&scope=${SCOPE}"
26MANIFEST_URL="https://ghcr.io/v2/${OWNER}/${IMAGE_NAME}/manifests/${TAG}"
27
28TOKEN_RESPONSE=$(curl --silent --user "${AUTH_USER}:${GH_PAT}" "${TOKEN_URL}")
29TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token')
30
31if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then
32 echo "Error: Failed to retrieve bearer token. Check credentials and permissions." >&2
33 echo "Server Response: ${TOKEN_RESPONSE}" >&2
34 exit 1
35fi
36
37curl --fail -i -H "Authorization: Bearer ${TOKEN}" "${MANIFEST_URL}"
Created on 10/6/2025