Skip to content

Commit d5e9c82

Browse files
authored
Merge pull request #1497 from github/jurre/registry-credentials
Use Registry Credentials when passed to env
2 parents f48674b + e1b95c1 commit d5e9c82

5 files changed

Lines changed: 130 additions & 5 deletions

File tree

__tests__/main.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {Updater} from '../src/updater'
1313
import {ImageService, MetricReporter} from '../src/image-service'
1414
import {updaterImageName} from '../src/docker-tags'
1515
import * as inputs from '../src/inputs'
16-
import {run} from '../src/main'
16+
import {run, credentialsFromEnv} from '../src/main'
1717

1818
import {eventFixturePath} from './helpers'
1919

@@ -787,3 +787,50 @@ describe('run', () => {
787787
})
788788
})
789789
})
790+
791+
describe('credentialsFromEnv', () => {
792+
const originalEnv = process.env.GITHUB_REGISTRIES_PROXY
793+
afterEach(() => {
794+
process.env.GITHUB_REGISTRIES_PROXY = originalEnv
795+
jest.clearAllMocks()
796+
})
797+
798+
it('returns an empty array if GITHUB_REGISTRIES_PROXY is not set', () => {
799+
delete process.env.GITHUB_REGISTRIES_PROXY
800+
expect(credentialsFromEnv()).toEqual([])
801+
})
802+
803+
it('returns an empty array if GITHUB_REGISTRIES_PROXY is not valid base64', () => {
804+
process.env.GITHUB_REGISTRIES_PROXY = 'not-base64!'
805+
expect(credentialsFromEnv()).toEqual([])
806+
})
807+
808+
it('returns an empty array if GITHUB_REGISTRIES_PROXY is not valid JSON', () => {
809+
process.env.GITHUB_REGISTRIES_PROXY =
810+
Buffer.from('not-json').toString('base64')
811+
expect(credentialsFromEnv()).toEqual([])
812+
})
813+
814+
it('returns parsed credentials and masks secrets', () => {
815+
const creds = [
816+
{
817+
url: 'https://foo',
818+
username: 'bar',
819+
password: 'baz',
820+
token: 'tok',
821+
host: 'h',
822+
'replaces-base': false
823+
}
824+
]
825+
process.env.GITHUB_REGISTRIES_PROXY = Buffer.from(
826+
JSON.stringify(creds)
827+
).toString('base64')
828+
const setSecretSpy = jest.spyOn(core, 'setSecret')
829+
const result = credentialsFromEnv()
830+
expect(result).toEqual(creds)
831+
expect(setSecretSpy).toHaveBeenCalledWith('baz')
832+
expect(setSecretSpy).toHaveBeenCalledWith('tok')
833+
expect(setSecretSpy).not.toHaveBeenCalledWith('bar')
834+
expect(setSecretSpy).not.toHaveBeenCalledWith('https://foo')
835+
})
836+
})

dist/main/index.js

Lines changed: 37 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/main/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api-client.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export type Credential = {
3737
'env-key'?: string
3838
'replaces-base'?: boolean
3939
'public-key-fingerprint'?: string
40+
'auth-key'?: string
4041
}
4142

4243
export type Metric = {
@@ -138,6 +139,9 @@ export class ApiClient {
138139
if (credential.token) {
139140
core.setSecret(credential.token)
140141
}
142+
if (credential['auth-key']) {
143+
core.setSecret(credential['auth-key'])
144+
}
141145
}
142146

143147
return res.result.data.attributes.credentials

src/main.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as core from '@actions/core'
22
import * as github from '@actions/github'
33
import * as httpClient from '@actions/http-client'
44
import {Context} from '@actions/github/lib/context'
5-
import {ApiClient, CredentialFetchingError} from './api-client'
5+
import {ApiClient, Credential, CredentialFetchingError} from './api-client'
66
import {getJobParameters} from './inputs'
77
import {ImageService, MetricReporter} from './image-service'
88
import {updaterImageName, PROXY_IMAGE_NAME} from './docker-tags'
@@ -89,7 +89,11 @@ export async function run(context: Context): Promise<void> {
8989
}
9090

9191
try {
92-
const credentials = await apiClient.getCredentials()
92+
const credentials = (await apiClient.getCredentials()) || []
93+
const registryCredentials = credentialsFromEnv()
94+
95+
credentials.push(...registryCredentials)
96+
9397
const updater = new Updater(
9498
updaterImage,
9599
PROXY_IMAGE_NAME,
@@ -215,4 +219,38 @@ function dependabotJobUrl(id: number): string {
215219
return url_parts.filter(Boolean).join('/')
216220
}
217221

222+
export function credentialsFromEnv(): Credential[] {
223+
const registriesProxyStr = process.env.GITHUB_REGISTRIES_PROXY
224+
let credentialsStr: string
225+
if (registriesProxyStr !== undefined) {
226+
credentialsStr = Buffer.from(registriesProxyStr, 'base64').toString()
227+
} else {
228+
return []
229+
}
230+
231+
let parsed: Credential[]
232+
233+
try {
234+
parsed = JSON.parse(credentialsStr) as Credential[]
235+
} catch {
236+
// Don't log the error as it may contain sensitive information
237+
parsed = []
238+
botSay('Failed to parse GITHUB_REGISTRIES_PROXY environment variable')
239+
}
240+
241+
const nonSecrets = ['url', 'username', 'host', 'replaces-base']
242+
for (const e of parsed) {
243+
// Mask credentials to reduce chance of accidental leakage in logs.
244+
for (const key of Object.keys(e)) {
245+
if (!nonSecrets.includes(key)) {
246+
core.setSecret((e as Record<string, unknown>)[key] as string)
247+
}
248+
}
249+
250+
// TODO: Filter down to only credentials relevant to this job.
251+
}
252+
253+
return parsed
254+
}
255+
218256
run(github.context)

0 commit comments

Comments
 (0)