mirror of
https://github.com/docker/login-action.git
synced 2026-05-10 12:32:10 +00:00
Implement native OIDC-based authentication for Chainguard's container registry, following the same pattern as the existing AWS ECR integration. When registry is set to cgr.dev, the action automatically exchanges a GitHub Actions OIDC token with Chainguard's STS endpoint for a short-lived registry credential, removing the need for chainctl or long-lived pull tokens. New inputs: chainguard (auto/true/false), chainguard-identity. Signed-off-by: Augustus Nguyen <theflash28012002@gmail.com>
105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import path from 'path';
|
|
import * as core from '@actions/core';
|
|
import * as yaml from 'js-yaml';
|
|
|
|
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
|
|
import {Util} from '@docker/actions-toolkit/lib/util.js';
|
|
|
|
export interface Inputs {
|
|
registry: string;
|
|
username: string;
|
|
password: string;
|
|
scope: string;
|
|
ecr: string;
|
|
chainguard: string;
|
|
chainguardIdentity: string;
|
|
logout: boolean;
|
|
registryAuth: string;
|
|
}
|
|
|
|
export interface Auth {
|
|
registry: string;
|
|
username: string;
|
|
password: string;
|
|
scope: string;
|
|
ecr: string;
|
|
chainguard: string;
|
|
chainguardIdentity: string;
|
|
configDir: string;
|
|
}
|
|
|
|
export function getInputs(): Inputs {
|
|
return {
|
|
registry: core.getInput('registry'),
|
|
username: core.getInput('username'),
|
|
password: core.getInput('password'),
|
|
scope: core.getInput('scope'),
|
|
ecr: core.getInput('ecr'),
|
|
chainguard: core.getInput('chainguard'),
|
|
chainguardIdentity: core.getInput('chainguard-identity'),
|
|
logout: core.getBooleanInput('logout'),
|
|
registryAuth: core.getInput('registry-auth')
|
|
};
|
|
}
|
|
|
|
export function getAuthList(inputs: Inputs): Array<Auth> {
|
|
if (inputs.registryAuth && (inputs.registry || inputs.username || inputs.password || inputs.scope || inputs.ecr || inputs.chainguard || inputs.chainguardIdentity)) {
|
|
throw new Error('Cannot use registry-auth with other inputs');
|
|
}
|
|
let auths: Array<Auth> = [];
|
|
if (!inputs.registryAuth) {
|
|
const registry = inputs.registry || 'docker.io';
|
|
auths.push({
|
|
registry,
|
|
username: inputs.username,
|
|
password: inputs.password,
|
|
scope: inputs.scope,
|
|
ecr: inputs.ecr || 'auto',
|
|
chainguard: inputs.chainguard || 'auto',
|
|
chainguardIdentity: inputs.chainguardIdentity,
|
|
configDir: scopeToConfigDir(registry, inputs.scope)
|
|
});
|
|
} else {
|
|
auths = (yaml.load(inputs.registryAuth) as Array<Auth>).map(auth => {
|
|
if (auth.password) {
|
|
core.setSecret(auth.password);
|
|
}
|
|
const registry = auth.registry || 'docker.io';
|
|
return {
|
|
registry,
|
|
username: auth.username,
|
|
password: auth.password,
|
|
scope: auth.scope,
|
|
ecr: auth.ecr || 'auto',
|
|
chainguard: auth.chainguard || 'auto',
|
|
chainguardIdentity: auth.chainguardIdentity,
|
|
configDir: scopeToConfigDir(registry, auth.scope)
|
|
};
|
|
});
|
|
}
|
|
if (auths.length == 0) {
|
|
throw new Error('No registry to login');
|
|
}
|
|
return auths;
|
|
}
|
|
|
|
export function scopeToConfigDir(registry: string, scope?: string): string {
|
|
if (scopeDisabled() || !scope || scope === '') {
|
|
return '';
|
|
}
|
|
let configDir = path.join(Buildx.configDir, 'config', registry === 'docker.io' ? 'registry-1.docker.io' : registry);
|
|
if (scope.startsWith('@')) {
|
|
configDir += scope;
|
|
} else {
|
|
configDir = path.join(configDir, scope);
|
|
}
|
|
return configDir;
|
|
}
|
|
|
|
function scopeDisabled(): boolean {
|
|
if (process.env.DOCKER_LOGIN_SCOPE_DISABLED) {
|
|
return Util.parseBool(process.env.DOCKER_LOGIN_SCOPE_DISABLED);
|
|
}
|
|
return false;
|
|
}
|