Skip to main content

Conjur Cloud Integration

ggscout supports integration with Conjur Cloud to collect and monitor your secrets. This guide will help you set up and configure the integration.

Supported Features

  • Multiple secret versions collection
  • CyberArk authentication
  • Tenant-specific configuration
  • Subdomain support

Configuration

The following table lists the available configuration options for ggscout when integrating with Conjur Cloud:

ParameterDescriptionRequiredDefault Value
typeMust be set to "conjurcloud"Yes
auth.auth_modeAuthentication mode (one of: "cyber_ark", "workload", "k8s")Yes
subdomainYour company's subdomainYes
fetch_all_versionsWhether to collect all versions of secretsYes
modeIntegration mode (one of: "read", "write", "read/write")No"read"
envEnvironment label for categorizing secrets (e.g., "production", "staging", "development")No
includeList of path patterns to include in secret collectionNo
excludeList of path patterns to exclude from secret collectionNo

With additional parameters depending on the chosen authentication mode:

For CyberArk Authentication:

ParameterDescriptionRequiredDefault Value
auth.client_idThe client ID for authenticationYes
auth.client_secretThe client secret for authenticationYes
auth.tenant_idThe tenant IDYes

For Workload Authentication:

ParameterDescriptionRequiredDefault Value
auth.api_keyYour Conjur API keyYes
auth.loginYour Conjur loginYes

For Kubernetes Authentication:

ParameterDescriptionRequiredDefault Value
auth.service_idThe ID of your JWT authenticator in Conjur CloudYes

Authentication

ggscout supports multiple authentication methods for Conjur Cloud:

CyberArk Authentication

[sources.conjur]
type = "conjurcloud"
auth.auth_mode = "cyber_ark"
auth.client_id = "${CYBERARK_CLIENT_ID}"
auth.client_secret = "${CYBERARK_CLIENT_SECRET}"
auth.tenant_id = "${CYBERARK_TENANT_ID}"
conjur_url = "${CONJUR_URL}"
subdomain = "my-company"
fetch_all_versions = true
mode = "read"
env = "production"

[[sources.conjur.include]]
resource_ids = ["app/*", "database/*", "api-key"]

[[sources.conjur.exclude]]
resource_ids = ["test/*", "temp/*", "old-secret"]

Workload Authentication

[sources.conjur]
type = "conjurcloud"
auth.auth_mode = "workload"
api_key = "${CONJUR_API_KEY}"
login = "${CONJUR_LOGIN}"
subdomain = "my-company"
fetch_all_versions = true
mode = "read"
env = "production"

[[sources.conjur.include]]
resource_ids = ["app/*", "database/*", "api-key"]

[[sources.conjur.exclude]]
resource_ids = ["test/*", "temp/*", "old-secret"]

Kubernetes Authentication

[sources.conjur]
type = "conjurcloud"
auth.auth_mode = "k8s"
auth.service_id = "k8s-cluster-name"
subdomain = "my-company"
fetch_all_versions = true
mode = "read"
env = "production"

[[sources.conjur.include]]
resource_ids = ["app/*", "database/*", "api-key"]

[[sources.conjur.exclude]]
resource_ids = ["test/*", "temp/*", "old-secret"]

Detailed Setup Instructions

For applications running in Kubernetes clusters, you can configure Conjur Cloud to use JWT-based authentication. This allows your Kubernetes workloads to authenticate with Conjur Cloud using service account tokens.

Prerequisites

  • A running Conjur Cloud instance
  • A running Kubernetes cluster
  • kubectl CLI installed and configured

Step 1: Retrieve Kubernetes OIDC Configuration

For AWS EKS

Get the OIDC issuer URL for your EKS cluster:

aws eks describe-cluster --name <YOUR_EKS_CLUSTER_NAME> --query "cluster.identity.oidc.issuer" --output text

The output will be a URL like https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED5A3C59576A0175F11F3414644.

The JWKS URI is the issuer URL with /keys appended: https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED5A3C59576A0175F11F3414644/keys

For Other Kubernetes Clusters

For clusters that expose the OIDC discovery endpoint:

# Get the OIDC issuer URL
kubectl get --raw /.well-known/openid-configuration | jq -r '.issuer'

# Get the public keys (JWKS)
kubectl get --raw /openid/v1/jwks

Step 2: Configure JWT Authenticator in Conjur Cloud

You can create the JWT authenticator using the Conjur Cloud UI, API, or CLI.

Using Conjur Cloud UI
  1. Navigate to the Authenticators page in Conjur Cloud
  2. Click Create authenticator
  3. Select JWT as the authenticator type
  4. Enter a unique name for the authenticator (e.g., k8s-cluster-name)
  5. Configure the following variables:
VariableDescriptionRequiredExample Value
jwks-uriThe JWKS URI of your Kubernetes clusterYes (or use public-keys)https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE/keys
public-keysJWKS content as JSON stringYes (or use jwks-uri)Use for local/private clusters
issuerThe OIDC issuer URLYeshttps://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE
token-app-propertyJWT claim for application identityYessub
audienceExpected audience for the JWTRecommendedconjur
Policy Example

When using policy files, your JWT authenticator policy should look like this:

- !policy
id: conjur/authn-jwt/k8s-cluster-name
body:
- !webservice
annotations:
description: JWT authenticator for Kubernetes cluster

- !variable
id: jwks-uri

- !variable
id: issuer

- !variable
id: token-app-property

- !variable
id: audience

- !group users

- !host-factory
id: host-factory
layers: [ !layer users ]

Then populate the variables:

# Set the JWKS URI
conjur variable set -i conjur/authn-jwt/k8s-cluster-name/jwks-uri -v "https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE/keys"

# Set the issuer
conjur variable set -i conjur/authn-jwt/k8s-cluster-name/issuer -v "https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE"

# Set the token app property (IMPORTANT: Use 'sub' for Kubernetes)
conjur variable set -i conjur/authn-jwt/k8s-cluster-name/token-app-property -v "sub"

# Set the audience
conjur variable set -i conjur/authn-jwt/k8s-cluster-name/audience -v "conjur"

Step 3: Create Workload Branch and Identity

Before creating workloads in Conjur Cloud, you need to set up the policy structure and workload identities.

Create Policy Branch (CLI Required)

If you're using the UI to create workloads, you must first create the policy branch using the CLI, as this cannot be done through the UI.

  1. Log in to Conjur Cloud CLI:

    conjur login
  2. Create the workload branch policy:

    Save the following as workload-branch.yaml:

    - !policy
    id: <policy-id>

    Where <policy-id> is the name of your branch (for example, myspace/jwt-apps or k8s-apps).

  3. Load the policy branch:

    conjur policy load -f workload-branch.yaml -b data
Create Workload Identity

After creating the policy branch, you can create the workload identity using either the UI or CLI.

Option A: Using Conjur Cloud UI
  1. Navigate to Workloads in the Conjur Cloud UI
  2. Click Create workload
  3. Select JWT as the authentication method
  4. Choose your JWT authenticator (e.g., k8s-cluster-name)
  5. Configure the workload:
    • Workload ID: system:serviceaccount:my-namespace:my-service-account
    • Policy Branch: The branch you created (e.g., myspace/jwt-apps)
    • Annotations: Add relevant metadata
      • kubernetes/namespace: my-namespace
      • kubernetes/service-account: my-service-account
Option B: Using CLI Policy (Detailed Steps)

Step 1: Create the workload host policy

Save the following policy in a file named authn-jwt-hosts.yaml:

- !policy
id: <policy-id>
body:
- !group
- !host
id: <host-id>
annotations:
authn-jwt/<service-id>/<jwt-claim-name>: <jwt-claim-value>

- !grant
role: !group
member: !host

Where:

  • <policy-id> is the name of the branch (e.g., myspace/jwt-apps or k8s-apps)
  • <host-id> is the name of the workload. For Kubernetes JWT authentication using token-app-property, this must be the value of the JWT claim (e.g., system:serviceaccount:my-namespace:my-service-account)
  • <service-id> is the name of your JWT authenticator (e.g., k8s-cluster-name)
  • <jwt-claim-name> is the name of a JWT claim (e.g., sub, namespace, etc.)
  • <jwt-claim-value> is the value of the specified JWT claim

For Kubernetes workloads, here's a concrete example using the sub claim:

- !policy
id: k8s-apps
body:
- !group
- !host
id: system:serviceaccount:ggscout-namespace:ggscout-service-account
annotations:
kubernetes/namespace: ggscout-namespace
kubernetes/service-account: ggscout-service-account
workload/type: ggscout

- !grant
role: !group
member: !host

Step 2: Load the workload policy

conjur policy load -f authn-jwt-hosts.yaml -b data

Step 3: Grant workload permissions to JWT authenticator

Create a policy file authn-jwt-grant.yaml:

- !grant
role: !group conjur/authn-jwt/k8s-cluster-name/users
member: !group /data/k8s-apps

Load the policy in the JWT authenticator branch:

conjur policy load -f authn-jwt-grant.yaml -b conjur/authn-jwt/k8s-cluster-name

Step 4: Create comprehensive workload policy with secrets

For a complete setup including secrets and permissions, create k8s-workload-complete.yaml:

- !policy
id: k8s-apps
body:
# Create the workload host with proper annotations
- !host
id: system:serviceaccount:ggscout-namespace:ggscout-service-account
annotations:
authn-jwt/k8s-cluster-name/sub: system:serviceaccount:ggscout-namespace:ggscout-service-account
kubernetes/namespace: ggscout-namespace
kubernetes/service-account: ggscout-service-account
description: "ggscout service account for Kubernetes cluster authentication"

# Create secrets that this workload can access
- !variable
id: database/password

- !variable
id: api/token

# Create a group for this workload's permissions
- !group
id: ggscout-consumers

# Grant the workload access to the consumer group
- !grant
role: !group ggscout-consumers
member: !host system:serviceaccount:ggscout-namespace:ggscout-service-account

# Grant read permissions to secrets
- !permit
role: !group ggscout-consumers
privilege: [ read, execute ]
resource: !variable database/password

- !permit
role: !group ggscout-consumers
privilege: [ read, execute ]
resource: !variable api/token

Load the complete policy:

conjur policy load -f k8s-workload-complete.yaml -b data
Multiple Workloads Example

For multiple Kubernetes workloads, you can create them in batch:

- !policy
id: myspace/jwt-apps
body:
# ggscout workload
- !host
id: system:serviceaccount:ggscout-namespace:ggscout-service-account
annotations:
kubernetes/namespace: ggscout-namespace
kubernetes/service-account: ggscout-service-account
workload/type: ggscout

# Application workload
- !host
id: system:serviceaccount:app-namespace:app-service-account
annotations:
kubernetes/namespace: app-namespace
kubernetes/service-account: app-service-account
workload/type: application

# Grant authentication permissions to both
- !grant
role: !group conjur/authn-jwt/k8s-cluster-name/users
members:
- !host system:serviceaccount:ggscout-namespace:ggscout-service-account
- !host system:serviceaccount:app-namespace:app-service-account
Workload Naming Conventions

For Kubernetes workloads using JWT authentication, follow these naming conventions:

  • Host ID Format: system:serviceaccount:<namespace>:<service-account-name>
  • Policy Branch: Use logical groupings like k8s-apps, <environment>/k8s, or <team>/jwt-workloads
  • Annotations: Include metadata for better organization:
    • kubernetes/namespace
    • kubernetes/service-account
    • environment (dev, staging, prod)
    • team or application

Step 4: Configure ggscout for JWT Authentication

Add the JWT authentication configuration to your ggscout.toml:

[sources.conjur-k8s]
type = "conjurcloud"
auth.auth_mode = "k8s"
auth.service_id = "k8s-cluster-name"
subdomain = "my-company"
fetch_all_versions = true
mode = "read"

Important Notes

  1. Always use sub as token-app-property: For Kubernetes workloads, the sub (subject) claim contains the service account identity in the format system:serviceaccount:<namespace>:<serviceaccount-name>.

  2. Follow least privilege: Create specific host identities for each workload and grant only the minimum required permissions.

  3. Workload ID matching: Ensure the workload ID in Conjur Cloud exactly matches the Kubernetes service account format: system:serviceaccount:<namespace>:<service-account-name>.

Step 6: Grant Access to Variables/Secrets

After creating your workload identity, you need to grant it access to the specific secrets it requires. This is done through Conjur Cloud's policy system using groups, layers, and permit statements.

Method 1: Direct Variable Assignment

Create variables and assign privileges directly to a group or layer:

- !policy
id: ggscout-secrets
body:
# Define the variables/secrets
- &variables
- !variable
id: db-password
kind: password

- !variable
id: api-token
kind: API token

- !variable
id: ssl/private_key
kind: SSL private key
mime_type: application/x-pem-file

# Create a layer for workloads that need these secrets
- !layer app

# Grant access to the variables
- !permit
role: !layer app
privileges: [read, execute]
resources: *variables

# Add your workload to the layer
- !grant
role: !layer app
member: !host /data/k8s-apps/system:serviceaccount:ggscout-namespace:ggscout-service-account
Method 2: Policy-Based Secret Organization

For better organization, create a dedicated policy for your application's secrets:

- !policy
id: ggscout-app-secrets
owner: !group devops
annotations:
description: This policy contains secrets for ggscout application

body:
# Define secret variables using YAML anchor
- &app-secrets
- !variable
id: database/password
- !variable
id: database/url
- !variable
id: database/username
- !variable
id: external-api/token
- !variable
id: encryption/key

# Create a group for consumers of these secrets
- !group consumers

# Grant read and execute permissions to the consumer group
- !permit
role: !group consumers
privileges: [ read, execute ]
resources: *app-secrets

# Add your ggscout workload to the consumers group
- !grant
role: !group consumers
member: !host /data/k8s-apps/system:serviceaccount:ggscout-namespace:ggscout-service-account
Load the Secret Policies

After creating your secret policies, load them into Conjur Cloud:

# Load the policy
conjur policy load -f ggscout-secrets.yaml -b data

# Set the secret values (example)
conjur variable set -i ggscout-secrets/db-password -v "your-secure-password"
conjur variable set -i ggscout-secrets/api-token -v "your-api-token"