Skip to content

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,
		}
	}
Edited by Jaime Martinez