Skip to content

Commit

Permalink
New OIDC auth method
Browse files Browse the repository at this point in the history
  • Loading branch information
rgharris committed Dec 3, 2024
1 parent 8ac64b8 commit b0a7fc9
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
12 changes: 11 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ branding:
icon: 'lock'
color: 'blue'
inputs:
auth-method:
description: >-
Auth method to use - set this to "oidc" for identity auth via OIDC.
Note that this requires the `id-token: write` permission on the Github
job or workflow. See https://docs.doppler.com/docs/service-account-identities
default: "token"
doppler-token:
description: >-
Doppler Service Token that grants access to a single Config within a Project.
See https://docs.doppler.com/docs/service-tokens
required: true
required: false
doppler-project:
description: >-
Doppler Project
Expand All @@ -21,6 +27,10 @@ inputs:
description: >-
Inject secrets as environment variables for subsequent steps if set to `true`.
required: false
doppler-identity-id:
description: >-
Identity to use, required when auth-method is "oidc".
required: false
runs:
using: 'node20'
main: 'index.js'
61 changes: 59 additions & 2 deletions doppler.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { VERSION } from "./meta.js";
* @param {string | null} [dopplerConfig]
* @returns {() => Promise<Record<string, Record>>}
*/
async function fetch(dopplerToken, dopplerProject, dopplerConfig) {
export async function fetch(dopplerToken, dopplerProject, dopplerConfig) {
return new Promise(function (resolve, reject) {
const encodedAuthData = Buffer.from(`${dopplerToken}:`).toString("base64");
const authHeader = `Basic ${encodedAuthData}`;
Expand Down Expand Up @@ -54,4 +54,61 @@ async function fetch(dopplerToken, dopplerProject, dopplerConfig) {
});
}

export default fetch;
/**
* Exchange an OIDC token for a short lived Doppler service account token
* @param {string} identityId
* @param {string} oidcToken
* @returns {() => Promise<string>}
*/
export async function oidcAuth(identityId, oidcToken) {
return new Promise(function (resolve, reject) {
const userAgent = `secrets-fetch-github-action/${VERSION}`;

const url = new URL("https://api.doppler.com/v3/auth/oidc");
const body = JSON.stringify({
identityId,
token: oidcToken
});

const request = https
.request(
url.href,
{
headers: {
Authorization: authHeader,
"user-agent": userAgent,
"accepts": "application/json",
"Content-Type": "application/json",
"Content-Length": body.length,
},
method: 'POST'
},
(res) => {
let payload = "";
res.on("data", (data) => (payload += data));
res.on("end", () => {
if (res.statusCode === 201) {
resolve(JSON.parse(payload).token);
} else {
try {
const error = JSON.parse(payload).messages.join(" ");
reject(new Error(`Doppler API Error: ${error}`));
} catch (error) {
// In the event an upstream issue occurs and no JSON payload is supplied
reject(new Error(`Doppler API Error: ${res.statusCode} ${res.statusMessage}`));
}
}
});
}
);

request
.on("error", (error) => {
reject(new Error(`Doppler API Error: ${error}`));
});

request.write(body);

request.end()
});
}
20 changes: 17 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import core from "@actions/core";
import fetch from "./doppler.js";
import { fetch, oidcAuth } from "./doppler.js";

// For local testing
if (process.env.NODE_ENV === "development" && process.env.DOPPLER_TOKEN) {
Expand All @@ -8,11 +8,25 @@ if (process.env.NODE_ENV === "development" && process.env.DOPPLER_TOKEN) {
process.env["INPUT_DOPPLER-CONFIG"] = process.env.DOPPLER_CONFIG;
}

const AUTH_METHOD = core.getInput("auth-method");
let DOPPLER_TOKEN = "";

if (AUTH_METHOD === "oidc") {
DOPPLER_IDENTITY_ID = core.getInput("doppler-identity-id", { required: true });
const oidcToken = core.getIDToken();
core.setSecret(oidcToken);
DOPPLER_TOKEN = await oidcAuth(DOPPLER_IDENTITY_ID, oidcToken)
} else if (AUTH_METHOD === "token") {
DOPPLER_TOKEN = core.getInput("doppler-token", { required: true });
}else {
core.setFailed("unexpected auth-method");
process.exit();
}

const DOPPLER_META = ["DOPPLER_PROJECT", "DOPPLER_CONFIG", "DOPPLER_ENVIRONMENT"];
const DOPPLER_TOKEN = core.getInput("doppler-token", { required: true });
core.setSecret(DOPPLER_TOKEN);

const IS_SA_TOKEN = DOPPLER_TOKEN.startsWith("dp.sa.");
const IS_SA_TOKEN = DOPPLER_TOKEN.startsWith("dp.sa.") || DOPPLER_TOKEN.startsWith("dp.said.");
const IS_PERSONAL_TOKEN = DOPPLER_TOKEN.startsWith("dp.pt.");
const DOPPLER_PROJECT = (IS_SA_TOKEN || IS_PERSONAL_TOKEN) ? core.getInput("doppler-project") : null;
const DOPPLER_CONFIG = (IS_SA_TOKEN || IS_PERSONAL_TOKEN) ? core.getInput("doppler-config") : null;
Expand Down

0 comments on commit b0a7fc9

Please sign in to comment.