Skip to content

joetanx/cjc-gitlab

Repository files navigation

1. Introduction

1.1. How does GitLab SaaS integration with Conjur Cloud using JWT work?

image

① Every GitLab CI/CD pipeline has a CI_JOB_JWT_V2 JSON web token in the predefined variables

  • Example JWT
{
  "namespace_id": "59407538",
  "namespace_path": "joetanx",
  "project_id": "46285066",
  "project_path": "joetanx/aws-cli-demo",
  "user_id": "12855715",
  "user_login": "joetanx",
  "user_email": "joe.tan@cyberark.com",
  "pipeline_id": "877636997",
  "pipeline_source": "push",
  "job_id": "4343330528",
  "ref": "main",
  "ref_type": "branch",
  "ref_path": "refs/heads/main",
  "ref_protected": "true",
  "jti": "f9fe5035-17f7-4259-b6f9-873fed0f57ea",
  "iss": "gitlab.com",
  "iat": 1684936926,
  "nbf": 1684936921,
  "exp": 1684940526,
  "sub": "job_4343330528"
}

Note

The value of CI_JOB_JWT_V2 is masked on GitLab jobs

To get the value:

  • use echo ${CI_JOB_JWT_V2} | base64

  • decode the base64 output

  • then decode the JWT

② The GitLab runner sends an authentication request to Conjur using REST API to the JWT authenticator URI (https://<subdomain>.secretsmgr.cyberark.cloud/api/authn-jwt/<service-id>)

  • The URI for this demo is https://apj-secrets.secretsmgr.cyberark.cloud/api/authn-jwt/jtan-gitlab

③ Conjur fetches the public key from the GitLab JWKS URI

  • The GibLab SaaS JWKS URI is at https://gitlab.com/-/jwks/
  • This JWKS URI is set in the jwks-uri variable of the JWT authenticator in Conjur so that Conjur knows where to find the JWKS

④ Conjur verifies that the token is legit with the JWKS public key and authenticates application identity

  • Conjur identifies the application identity via the token-app-property variable of the JWT authenticator
  • The token-app-property variable is set in Conjur as the project_path claim in this demo
  • Conjur further verifies the applications details as configured in the annotations listed in the host (application identity) declaration
  • The annotations can be any claims on the JWT that do not change on a per-run basis, e.g. namespace_id, namespace_path, project_path

⑤ Conjur returns an access token to the GitLab runner if authentication is successful

⑥ The GitLab runner will then use the access token to retrieve the secrets using REST API to the secrets URI

1.2. GitLab free account and GitLab SaaS runners

GitLab free tier entitles 400 units of compute per month to run GitLab SaaS runners

Credit card information is required to use GitLab SaaS runners

image

The small machine type is the default and consumes compute units at 1 CI/CD minute cost factor rate

2. Preparation

2.1. AWS account

The jobs to be run on GitLab uses an AWS Secret Access Key

The IAM role will need to have the permissions for S3 access and access key rotation

2.2. Onboard AWS account to Privilege Cloud

Ref: https://docs.cyberark.com/Product-Doc/OnlineHelp/PAS/Latest/en/Content/PASIMP/AmazonWebServicesAccessKeys.htm

image

2.3. Configure account sync from Privilege Cloud to Conjur Cloud

Ref: https://docs.cyberark.com/Product-Doc/OnlineHelp/ConjurCloud/Latest/en/Content/HomeTilesLPs/LP-Tile4.htm

image

image

image

image

3. Conjur policies for GitLab JWT

3.1. Details of Conjur policies used in this demo

3.1.1. gitlab-hosts.yaml

  • jtan/gitlab - policy name, this forms the identity-path of the app IDs
  • applications joetanx/aws-cli-demo, joetanx/terraform-aws-s3-demo and joetanx/terraform-aws-s3-cleanup are configured
    • the id of the host corresponds to the token-app-property
    • annotations of the host are optional and corresponds to claims in the JWT token claims - the more specific the annotations/claims configured, the more precise and secure the application authentication
  • the host layer is granted as a member of the vault/jtan/delegation/consumers group to authorize access to the AWS secret access key synchronized from Privilege Cloud

3.1.2. authn-jwt-gitlab.yaml

Variables Description
jwks-uri JSON Web Key Set (JWKS) URI. For GitLab this is https://gitlab.com/-/jwks/.
token-app-property The JWT claim to be used to identify the application. This demo uses the project_path claim from GitLab.
identity-path The Conjur policy path where the hosts are defined in Conjur policy. The hosts in gitlab-hosts.yaml are created under jtan/gitlab, so the identity-path is data/jtan/gitlab.
issuer URI of the JWT issuer. This is the GitLab URL. This is included in iss claim in the JWT token claims.
  • Defines consumers group - applications that are authorized to authenticate using this JWT authenticator are added to this group
  • Defines operators group - users who are authorized to check the status of this JWT authenticator are added to this group

3.2. Load the Conjur policies and prepare Conjur for GitLab JWT

Login to Conjur:

conjur init -u https://<subdomain>.secretsmgr.cyberark.cloud/api
conjur login -i <username> -p <password>

Download and load the Conjur policies:

curl -sLO https://github.com/joetanx/cjc-gitlab/raw/main/authn-jwt-gitlab.yaml
curl -sLO https://github.com/joetanx/cjc-gitlab/raw/main/gitlab-hosts.yaml
conjur policy load -b conjur/authn-jwt -f authn-jwt-gitlab.yaml
conjur policy load -b data -f gitlab-hosts.yaml

Enable the JWT Authenticator:

conjur authenticator enable --id authn-jwt/jtan-gitlab

Populate the variables:

conjur variable set -i conjur/authn-jwt/jtan-gitlab/jwks-uri -v https://gitlab.com/-/jwks/
conjur variable set -i conjur/authn-jwt/jtan-gitlab/token-app-property -v project_path
conjur variable set -i conjur/authn-jwt/jtan-gitlab/identity-path -v data/jtan/gitlab
conjur variable set -i conjur/authn-jwt/jtan-gitlab/issuer -v https://gitlab.com

4. GitLab Projects

4.1. AWS CLI Demo

This project tests retrieval of the AWS secret access key from Conjur

4.1.1. Create a new project

GitLab project name: AWS CLI Demo

☝️ Project name is important! The project path must match the host identity configured in the Conjur policy

image

4.1.2. Create the main.tf file

image

4.1.3. Edit the GitLab CI/CD file

There are 2 stages in the pipeline code below:

  1. Fetch variables from Conjur (using CyberArk GitLab runner image)
  • Authenticate to Conjur authn-jwt/jtan-gitlab using CI_JOB_JWT_V2
  • Retrive AWS credentials
  • Pass the credentials to the next stage using artifacts:, reports:, dotenv:
  1. Test the AWS credentials
  • Run Terraform using docker.io/hashicorp/terraform:latest image
  • Run AWS CLI using docker.io/amazon/aws-cli:latest image

variables:
AWS_REGION: ap-southeast-1
CONJUR_APPLIANCE_URL: "https://apj-secrets.secretsmgr.cyberark.cloud/api"
CONJUR_ACCOUNT: "conjur"
CONJUR_AUTHN_JWT_SERVICE_ID: "jtan-gitlab"
CONJUR_AUTHN_JWT_TOKEN: "${CI_JOB_JWT_V2}"
Fetch variables from Conjur:
stage: .pre
image:
name: docker.io/cyberark/authn-jwt-gitlab:alpine-1.0.0
script:
- echo AWS_ACCESS_KEY_ID=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/AWSAccessKeyID" /authn-jwt-gitlab) >> conjurVariables.env
- echo AWS_SECRET_ACCESS_KEY=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/password" /authn-jwt-gitlab) >> conjurVariables.env
artifacts:
reports:
dotenv: conjurVariables.env
Run AWS CLI:
stage: test
image:
name: docker.io/amazon/aws-cli:latest
entrypoint: [""]
script:
- aws sts get-caller-identity
Check caller AWS STS token via Terraform using variables from Conjur:
stage: test
image:
name: docker.io/hashicorp/terraform:latest
entrypoint: [""]
before_script:
- terraform init
script:
- terraform plan

image

4.1.4. Pipeline run results

All jobs passed in the pipeline:

image

Output for fetch variables job:

image

Output for Terraform job:

image

Output for AWS CLI job:

image

4.2. Terraform AWS S3 Demo

This project demostrates the use of AWS secret access key retrieved from Conjur to create a S3 bucket

4.2.1. Create a new project

GitLab project name: Terraform AWS S3 Demo

☝️ Project name is important! The project path must match the host identity configured in the Conjur policy

image

4.2.2. Create the demo.txt, main.tf and provider.tf files

image

4.2.3. Edit the GitLab CI/CD file

There are 2 stages in the pipeline code below:

  1. Fetch variables from Conjur (using CyberArk GitLab runner image)
  • Authenticate to Conjur authn-jwt/jtan-gitlab using CI_JOB_JWT_V2
  • Retrive AWS credentials
  • Pass the credentials to the next stage using artifacts:, reports:, dotenv:
  1. Run Terraform to create S3 bucket according to main.tf using credentials from Conjur

variables:
AWS_REGION: ap-southeast-1
CONJUR_APPLIANCE_URL: "https://apj-secrets.secretsmgr.cyberark.cloud/api"
CONJUR_ACCOUNT: "conjur"
CONJUR_AUTHN_JWT_SERVICE_ID: "jtan-gitlab"
CONJUR_AUTHN_JWT_TOKEN: "${CI_JOB_JWT_V2}"
Fetch variables from Conjur:
stage: .pre
image:
name: docker.io/cyberark/authn-jwt-gitlab:alpine-1.0.0
script:
- echo AWS_ACCESS_KEY_ID=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/AWSAccessKeyID" /authn-jwt-gitlab) >> conjurVariables.env
- echo AWS_SECRET_ACCESS_KEY=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/password" /authn-jwt-gitlab) >> conjurVariables.env
artifacts:
reports:
dotenv: conjurVariables.env
Run Terraform using variables from Conjur:
stage: deploy
image:
name: docker.io/hashicorp/terraform:latest
entrypoint: [""]
before_script:
- terraform init
script:
- terraform apply -auto-approve

image

4.2.4. Pipeline run results

Both jobs passed in the pipeline:

image

Output for fetch variables job:

image

Output for Terraform job:

image

4.3. Terraform AWS S3 Cleanup

This project is used to verify the bucket created from the demo job above

4.3.1. Create a new project

GitLab project name: Terraform AWS S3 Cleanup

☝️ Project name is important! The project path must match the host identity configured in the Conjur policy

image

4.3.2. Edit the GitLab CI/CD file

There are 3 stages in the pipeline code below:

  1. Fetch variables from Conjur (using CyberArk GitLab runner image)
  • Authenticate to Conjur authn-jwt/jtan-gitlab using CI_JOB_JWT_V2
  • Retrive AWS credentials
  • Pass the credentials to the next stage using artifacts:, reports:, dotenv:
  1. Run AWS CLI to get the demo file from the S3 bucket created above using credentials from Conjur
  2. Manual job to delete the bucket

variables:
AWS_REGION: ap-southeast-1
CONJUR_APPLIANCE_URL: "https://apj-secrets.secretsmgr.cyberark.cloud/api"
CONJUR_ACCOUNT: "conjur"
CONJUR_AUTHN_JWT_SERVICE_ID: "jtan-gitlab"
CONJUR_AUTHN_JWT_TOKEN: "${CI_JOB_JWT_V2}"
Fetch variables from Conjur:
stage: .pre
image:
name: docker.io/cyberark/authn-jwt-gitlab:alpine-1.0.0
script:
- echo AWS_ACCESS_KEY_ID=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/AWSAccessKeyID" /authn-jwt-gitlab) >> conjurVariables.env
- echo AWS_SECRET_ACCESS_KEY=$(CONJUR_SECRET_ID="data/vault/jtan/Cloud Service-aws-access-keys-jtan-jtan-cjc/password" /authn-jwt-gitlab) >> conjurVariables.env
artifacts:
reports:
dotenv: conjurVariables.env
Verify bucket:
stage: test
image:
name: docker.io/amazon/aws-cli:latest
entrypoint: [""]
script:
- aws s3 ls s3://jtan-tfdemo
- aws s3 cp s3://jtan-tfdemo/demo.txt .
- cat ./demo.txt
Delete bucket:
stage: deploy
image:
name: docker.io/amazon/aws-cli:latest
entrypoint: [""]
script:
- aws s3 rb s3://jtan-tfdemo --force
rules:
- when: manual

image

4.2.3. Pipeline run results

Both jobs passed in the pipeline (manual job is pending manual activation):

image

Output for fetch variables job:

image

Output for AWS CLI job:

image

Proceed to run the last job to delete bucket:

image

Output for delete bucket job:

image

5. Audit Events

Activities in Conjur Cloud can be viewed on CyberArk Audit where details of the action (e.g. authenicate, fetch) and the host identities are recorded

image

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages