Managing Secrets
Create, use, rotate, and manage secrets throughout their lifecycle. This guide covers the complete set of operations for working with secrets in Harness 3.0, including UI workflows, pipeline usage, API access, and Terraform automation.
Creating Secrets
Secrets can be created at the Account, Organization, or Project scope depending on your navigation context.
-
Navigate to Secrets — Go to your Project, Organization, or Account settings. Select Secrets from the left navigation menu.
-
Choose Secret Type — Click + New Secret and select either Text or File based on the type of credential you need to store.
-
Configure Details — Provide a Name for the secret. The Identifier is auto-generated from the name but can be customized. Enter the secret Value (for text secrets) or upload the File (for file secrets).
-
Advanced Configuration — Select the Secret Manager to use for storing the encrypted value. The Harness built-in manager is selected by default. Choose an external manager if your organization requires it.
-
Optional Metadata — Add optional Tags to organize and filter secrets (e.g.,
env:prod,team:platform). Add an optional Description for documentation purposes. -
Save — Click Save to create the secret. The value is encrypted and stored in the selected secret manager. The secret is now available for use in pipelines and connectors within its scope.
Using Secrets in Pipelines
Secrets can be referenced in multiple contexts within your pipeline configuration. The secret value is resolved at runtime and automatically masked in execution logs.
In Connector Configuration
version: 1
kind: connector
spec:
name: Docker Hub
type: docker_registry
spec:
url: https://index.docker.io/v2/
authentication:
type: username_password
spec:
username: myuser
password: <+secrets.getValue("dockerhub_password")>
In Pipeline Variables
pipeline:
name: Deploy Application
variables:
- name: api_key
type: secret
value: <+secrets.getValue("prod_api_key")>
- name: db_password
type: secret
value: <+secrets.getValue("org.shared_db_password")>
stages:
- name: Deploy
type: deploy
spec:
service: my_service
environment:
name: production
deploy-to: production
In Shell Scripts
#!/bin/bash
# Secret values are resolved before script execution
export API_KEY=<+secrets.getValue("api_key")>
export DB_HOST=<+pipeline.variables.db_host>
export DB_PASS=<+secrets.getValue("db_password")>
# Use the resolved values
curl -s -H "Authorization: Bearer $API_KEY" \
https://api.example.com/health
# Connect to database
psql "host=$DB_HOST user=deploy password=$DB_PASS dbname=app" \
-c "SELECT version();"
In Service Definitions
version: 1
kind: service
spec:
name: Payment Service
type: kubernetes
spec:
manifests:
- type: k8s
spec:
store:
type: git
spec:
connector: github_connector
repo: payment-service
branch: main
paths:
- k8s/
variables:
- name: STRIPE_KEY
type: secret
value: <+secrets.getValue("stripe_api_key")>
- name: JWT_SECRET
type: secret
value: <+secrets.getValue("jwt_signing_key")>
Using File Secrets
File secrets require base64 decoding when used in shell scripts:
#!/bin/bash
# Retrieve and decode a file secret (e.g., GCP service account key)
echo '<+secrets.getValue("gcp_sa_key")>' | base64 -d > /tmp/sa-key.json
# Authenticate with GCP using the decoded key file
gcloud auth activate-service-account --key-file=/tmp/sa-key.json
# Retrieve and write a kubeconfig file
echo '<+secrets.getValue("prod_kubeconfig")>' | base64 -d > /tmp/kubeconfig
export KUBECONFIG=/tmp/kubeconfig
# Use kubectl with the decoded kubeconfig
kubectl get pods -n production
# Clean up sensitive files after use
rm -f /tmp/sa-key.json /tmp/kubeconfig
File secrets are stored as base64-encoded content. Always pipe the secret value through base64 -d before writing to a file. Clean up decoded files after use to avoid leaving sensitive data on disk.
Rotating Secrets
Regular secret rotation reduces the impact of credential compromise. Harness supports both manual rotation through the UI and automated rotation through external secret managers.
Manual Rotation
- Generate the new credential value in the source system (e.g., create a new API token in GitHub).
- Navigate to the secret in Harness and click Edit.
- Enter the new secret value and click Save.
- Verify that existing pipelines and connectors work correctly with the new value by running a test execution.
- Revoke the old credential value in the source system once the new value is confirmed working.
Automated Rotation with External Managers
When using an external secret manager with automated rotation (such as AWS Secrets Manager rotation lambdas or Vault dynamic secrets), Harness automatically retrieves the latest value at pipeline execution time. No manual intervention is required in Harness.
Emergency Rotation
If a secret is compromised: (1) Update the secret value in Harness or your external secret manager. (2) Revoke the compromised credential in the source system. (3) Review audit logs to identify any unauthorized access. (4) Run affected pipelines to verify the new credential works. (5) Report the incident per your organization's security policy.
Viewing and Searching Secrets
List View Columns
| Column | Description |
|---|---|
| Name | Secret name and identifier |
| Type | SecretText or SecretFile |
| Secret Manager | The backend storing the encrypted value |
| Scope | Account, Organization, or Project |
| Tags | Assigned metadata tags |
| Last Modified | Timestamp of the last update |
| References | Count of pipelines, connectors, and services using this secret |
Search and Filters
Use the search bar to find secrets by name or identifier. Apply filters to narrow results by Secret Manager, Scope (Account/Org/Project), Tags, Type (SecretText/SecretFile), or Usage (in use vs. unused).
Sort the secrets list by Name, Last Modified, Type, or References count. Click a column header to toggle ascending and descending order.
Secret Details View
Click on a secret to open its details view. The details page has three tabs:
- Configuration — View and edit the secret name, identifier, description, tags, and secret manager. The value is never displayed.
- References — See all pipelines, connectors, and services that reference this secret, with direct links to each entity.
- Activity — View the complete audit trail including creation, modification, access events, and the user who performed each action.
Deleting Secrets
Before deleting a secret, verify that it is not referenced by any active pipeline, connector, or service. Deleting a secret that is in use will cause pipeline failures.
- Open the secret details and navigate to the References tab. If the secret has active references, update or remove those references before proceeding.
- Navigate to the secret in the Secrets list.
- Click the three-dot menu on the secret row and select Delete.
- Confirm the deletion in the dialog. This action cannot be undone.
Always check the References tab before deleting a secret. Harness will warn you if the secret has active references, but it will not prevent deletion — the referencing resources will fail at execution time.
API and Automation
Harness provides a REST API and Terraform provider for automating secret management.
REST API
All requests require an API key with appropriate permissions. Base URL: https://app.harness.io/gateway/ng/api/v2/secrets
# List secrets
curl -X GET \
"https://app.harness.io/gateway/ng/api/v2/secrets?accountIdentifier=abc123&projectIdentifier=myproject" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json"
# Create a text secret
curl -X POST \
"https://app.harness.io/gateway/ng/api/v2/secrets?accountIdentifier=abc123" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"secret": {
"type": "SecretText",
"name": "My API Key",
"identifier": "my_api_key",
"orgIdentifier": "default",
"projectIdentifier": "myproject",
"spec": {
"secretManagerIdentifier": "harnessSecretManager",
"valueType": "Inline",
"value": "sk-xxxxxxxxxxxxxxxxxxxx"
}
}
}'
# Update a text secret value
curl -X PUT \
"https://app.harness.io/gateway/ng/api/v2/secrets/my_api_key?accountIdentifier=abc123" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"secret": {
"type": "SecretText",
"name": "My API Key",
"identifier": "my_api_key",
"orgIdentifier": "default",
"projectIdentifier": "myproject",
"spec": {
"secretManagerIdentifier": "harnessSecretManager",
"valueType": "Inline",
"value": "sk-new-value-xxxxxxxxxxxx"
}
}
}'
# Delete a secret
curl -X DELETE \
"https://app.harness.io/gateway/ng/api/v2/secrets/my_api_key?accountIdentifier=abc123&projectIdentifier=myproject" \
-H "x-api-key: YOUR_API_KEY"
Terraform Provider
resource "harness_platform_secret_text" "api_key" {
identifier = "api_key"
name = "API Key"
description = "Production API key for external service"
org_id = "default"
project_id = "myproject"
secret_manager_identifier = "harnessSecretManager"
value_type = "Inline"
value = var.api_key_value
tags = [
"env:prod",
"team:platform",
]
}
resource "harness_platform_secret_file" "gcp_sa_key" {
identifier = "gcp_sa_key"
name = "GCP Service Account Key"
description = "Service account key for GCP access"
org_id = "default"
project_id = "myproject"
secret_manager_identifier = "harnessSecretManager"
file_path = var.gcp_sa_key_path
tags = [
"env:prod",
"provider:gcp",
]
}
secret:
type: SecretText
name: GitHub PAT
identifier: github_pat
orgIdentifier: default
projectIdentifier: myproject
spec:
secretManagerIdentifier: harnessSecretManager
valueType: Inline
API keys used for secret management must have the appropriate RBAC permissions. Ensure the API key's service account has at minimum secret_edit permissions for creating and updating secrets, and secret_delete for deletion operations.