Authentication With X.509 Certificates
Summary
release-cli currently does not support authentication via X.509 client certificates.
Steps to reproduce
A self hosted gitlab instance with certificate authentication is required.
Example Project
Only available with a gitlab instance that uses certificate authentication.
Error can be reproduced with the following .gitlab-ci.yml
forge:
image: alpine
stage: build
script:
- echo "forged artifact" > artifact
artifacts:
paths: ["artifact"]
expire_in: 1 week
release_job:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo 'running release_job'
needs:
- job: forge
artifacts: true
release:
name: 'Release $CI_COMMIT_TAG'
description: 'Created using the release-cli'
tag_name: '$CI_COMMIT_TAG'
ref: '$CI_COMMIT_TAG'
milestones:
- 'm1'
- 'm2'
- 'm3'
released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
What is the current bug behavior?
The web server won't allow access to gitlab due to the missing X.509 authentication when using release-cli
What is the expected correct behavior?
release-cli implements flags to provide a TLS cert, key and CA
Relevant logs and/or screenshots
not available
Workaround
A quick dirty fix with hard coded paths for people who rely on certificate authentication is to clone the official repository and use the following clientFn function in master/internal/app/app.go. (sorry my golang knowledge is pretty bad, so didn't bother to implement it properly nor to create a PR)
clientFn := func(ctx *cli.Context) gitlab.HTTPClient {
certFile := "/certs/crt.pem"
keyFile := "/certs/key.pem"
caFile := "/certs/ca.crt"
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal(err)
}
caCert, err := ioutil.ReadFile(caFile)
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}
return &http.Client{
Timeout: ctx.Duration(flags.Timeout),
Transport: transport,
}
}