Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docker): Support for Bearer token to access the Docker registry #10400

Merged
merged 33 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c85b21d
Support for Bearer token to access the Docker registry
nielsbasjes Jun 11, 2021
8a6fe84
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
a4cf412
Fix typo in documentation
nielsbasjes Jun 11, 2021
7c46429
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
9772c93
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
b14d469
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
a988c7f
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
b66dbed
Update lib/datasource/docker/common.ts
nielsbasjes Jun 11, 2021
8351398
Update docs/usage/docker.md
nielsbasjes Jun 11, 2021
b64cb2d
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
786a648
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
21d38f6
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
3cdcc88
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
397755b
Add debug log of the step to applySecrets
nielsbasjes Jun 12, 2021
0997200
Improve documentation.
nielsbasjes Jun 12, 2021
d87a86b
Improve documentation.
nielsbasjes Jun 12, 2021
ec9a340
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
862c955
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
a82ba91
Update docs/usage/docker.md
nielsbasjes Jun 12, 2021
6954f50
Update lib/config/secrets.ts
nielsbasjes Jun 16, 2021
4f6280a
Update lib/datasource/docker/common.spec.ts
nielsbasjes Jun 16, 2021
c85915f
Update lib/datasource/docker/common.spec.ts
nielsbasjes Jun 16, 2021
10b523f
Update lib/datasource/docker/common.spec.ts
nielsbasjes Jun 16, 2021
a0370ec
Update lib/datasource/docker/common.ts
nielsbasjes Jun 16, 2021
144c0ad
Merge branch 'main' into DockerBearerToken
rarkins Jun 16, 2021
d6e77f2
Log authentication as trace instead of debug.
nielsbasjes Jun 16, 2021
959d912
Fix prettier
nielsbasjes Jun 16, 2021
a8c76d1
Update docs/usage/docker.md
nielsbasjes Jun 16, 2021
ead8c9c
Update docs/usage/docker.md
nielsbasjes Jun 16, 2021
9a2d13a
Improve documentation
nielsbasjes Jun 16, 2021
ae6a736
Merge branch 'main' into DockerBearerToken
viceice Jun 16, 2021
cd3ef36
Merge branch 'main' into DockerBearerToken
viceice Jun 16, 2021
4d3b3bd
Merge branch 'main' into DockerBearerToken
rarkins Jun 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/usage/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,53 @@ module.exports = {
};
```

#### Google Container Registry

Assume you are running GitLab CI in the Google Cloud, and you are storing your Docker images in the Google Container Registry (GCR).

Access to the GCR uses Bearer token based authentication.
This token can be obtained by running `gcloud auth print-access-token`, which requires the Google Cloud SDK to be installed.

The token expires after 60 minutes so you cannot store it in a variable for subsequent builds (like you can with `RENOVATE_TOKEN`).

When running Renovate in this context the Google access token must be retrieved and injected into the `hostRules` configuration just before Renovate is started.

_This documentation gives **a few hints** on **a possible way** to achieve this end result._

The basic approach is that you create a custom image and then run Renovate as one of the stages of your project.
To make this run independent of any user you should use a [`Project Access Token`](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html) (with Scopes: `api`, `read_api` and `write_repository`) for the project and use this as the `RENOVATE_TOKEN` variable for Gitlab CI.
See also the [renovate-runner repository on GitLab](https://gitlab.com/renovate-bot/renovate-runner) where `.gitlab-ci.yml` configuration examples can be found.

To get access to the token a custom Renovate Docker image is needed that includes the Google Cloud SDK.
The Dockerfile to create such an image can look like this:

```Dockerfile
FROM renovate/renovate:25.40.1
nielsbasjes marked this conversation as resolved.
Show resolved Hide resolved
# Include the "Docker tip" which you can find here https://cloud.google.com/sdk/docs/install
# under "Installation" for "Debian/Ubuntu"
RUN ...
```

For Renovate to access the Google Container Registry (GCR) it needs the current Google Access Token.
The configuration fragment to do that looks something like this:

```js
hostRules: [
{
matchHost: 'eu.gcr.io',
token: 'MyReallySecretTokenThatExpiresAfter60Minutes',
},
];
```

One way to provide the short-lived Google Access Token to Renovate is by generating these settings into a `config.js` file from within the `.gitlab-ci.yml` right before starting Renovate:

```yaml
script:
- 'echo "module.exports = { hostRules: [ { matchHost: ''eu.gcr.io'', token: ''"$(gcloud auth print-access-token)"'' } ] };" > config.js'
- renovate $RENOVATE_EXTRA_FLAGS
```

#### ChartMuseum

Maybe you're running your own ChartMuseum server to host your private Helm Charts.
Expand Down
45 changes: 45 additions & 0 deletions lib/datasource/docker/common.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as httpMock from '../../../test/http-mock';
import { getName, mocked } from '../../../test/util';
import * as _hostRules from '../../util/host-rules';
import * as dockerCommon from './common';
Expand Down Expand Up @@ -70,4 +71,48 @@ describe(getName(), () => {
`);
});
});
describe('getAuthHeaders', () => {
beforeEach(() => {
httpMock
.scope('https://my.local.registry')
.get('/v2/')
.reply(401, '', { 'www-authenticate': 'Authenticate you must' });
hostRules.hosts.mockReturnValue([]);
});

it('returns "authType token" if both provided', async () => {
hostRules.find.mockReturnValue({
authType: 'some-authType',
token: 'some-token',
});

const headers = await dockerCommon.getAuthHeaders(
'https://my.local.registry',
'https://my.local.registry/prefix'
);

expect(headers).toMatchInlineSnapshot(`
Object {
"authorization": "some-authType some-token",
}
`);
});

it('returns "Bearer token" if only token provided', async () => {
hostRules.find.mockReturnValue({
token: 'some-token',
});

const headers = await dockerCommon.getAuthHeaders(
'https://my.local.registry',
'https://my.local.registry/prefix'
);

expect(headers).toMatchInlineSnapshot(`
Object {
"authorization": "Bearer some-token",
}
`);
});
});
});
10 changes: 9 additions & 1 deletion lib/datasource/docker/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,20 @@ export async function getAuthHeaders(
'base64'
);
opts.headers = { authorization: `Basic ${auth}` };
} else if (opts.token) {
const authType = opts.authType ?? 'Bearer';
logger.trace(
`Using ${authType} token for Docker registry ${registryHost}`
);
opts.headers = { authorization: `${authType} ${opts.token}` };
return opts.headers;
}
delete opts.username;
delete opts.password;
delete opts.token;

if (authenticateHeader.scheme.toUpperCase() === 'BASIC') {
logger.debug(`Using Basic auth for docker registry ${dockerRepository}`);
logger.trace(`Using Basic auth for docker registry ${registryHost}`);
await http.get(apiCheckUrl, opts);
return opts.headers;
}
Expand Down