Overview and Setup of HashiCorp Vault in the C3 Agentic AI Platform
The C3 Agentic AI Platform uses the C3 AI Vault, a secret store that is backed by the C3 AI File System, to securely manage and administer secrets. The C3 AI Vault uses a dedicated vault directory with restrictive permissions, enabling on the the C3 AI Server to read and write to it.
The C3 Agentic AI Platform can integrate with HashiCorp Vault to provide secure storage of private information, such as secrets. With this integration, the functionality of the C3 AI Vault (that is, the getSecret and setSecret APIs) is maintained except the secrets are stored in the HashiCorp Vault instance, providing a secure, auditable, and versioned data store.
The purpose of this section is to provide a C3 AI Cluster Administrator with instructions to integrate an HashiCorp instance with the C3 Agentic AI Platform.
NOTE: To complete the integration, the C3 AI Cluster Administrator might need to obtain information from the Operations / Infrastructure Administrator and HashiCorp Vault Administrator to complete the integration.
Prerequisites
C3 Agentic AI Platform 8.4 and above
HashiCorp Vault v1.15.5 and above:
Authentication scheme and credentials (for example, token)
Vault URL
Any customer-specific details (for example, namespace)
Local setup of HashiCorp Vault
Start the Vault Server
To start the Vault server in development mode, use the following HashiCorp Terraform CLI command:
vault server -devAfter starting the server, set the VAULT_ADDR environment variable:
export VAULT_ADDR=http://127.0.0.1:8200Configure BootConfig for authentication
Vault supports various authentication methods. The configuration steps for token and appRole are provided below.
Token authentication
When starting Vault, the root token is output as part of the logs.
Modify BootConfig to use authKind=token, including the token.
{
"type": "BootConfig",
"config": {
"root": "mem:///secret/config",
"owner": "c3"
},
"vault": {
"root": "mem:///secret/vault",
"vaultKind": "hashicorp",
"url": "http://localhost:8200",
"authKind": "token",
"token": "{token here}"
}
}AppRole authentication
Create a Policy for AppRole.
Create a policy file (e.g., c3-policy.hcl) and define the necessary permissions:
Textpath "secret/*" { capabilities = ["create", "read", "update", "delete", "list", "sudo"] }Apply the policy:
Textvault policy write c3 c3-policy.hclEnable AppRole Authentication.
Enable appRole authentication and configure a role:
Textvault auth enable approle vault write auth/approle/role/c3-role token_policies="default, c3-tester"Get Role ID and Secret ID.
Obtain the role ID:
Textvault read auth/approle/role/c3/role-idCreate and retrieve the secret ID:
Textvault write -f auth/approle/role/c3/secret-idConfigure BootConfig.
Update BootConfig to use authKind=appRole, including the roleId and secretId:
JSON{ "type": "BootConfig", "config": { "root": "mem:///secret/config", "owner": "c3" }, "vault": { "root": "mem:///secret/vault", "vaultKind": "hashicorp", "url": "http://localhost:8200", "authKind": "appRole", "roleId": "{roleid}", "secretId": "{secretid}" } }
Kubernetes setup
Vault modes
Dev mode
Dev Server Mode: Ideal for development, testing, or learning purposes. Storage is entirely in-memory, which means restarting the pod will cause all secrets to be lost. This mode should not be used if you need persistence.
Command Linehelm repo add hashicorp https://helm.releases.hashicorp.com helm upgrade --install vault hashicorp/vault --set server.dev.enabled=true
Standalone mode
Default mode: Starts only 1 pod and initializes a Persistent Volume Claim (PVC) for storage.
Command Linehelm upgrade --install vault hashicorp/vault
High Availability (HA) mode
High Availability (HA): Enables running multiple instances of Vault in a cluster to ensure availability.
Create a
values.custom.yamlfile with the following configuration:YAMLserver: standalone: enabled: false ha: enabled: true replicas: 3 raft: enabled: true setNodeId: true config: | ui = true listener "tcp" { tls_disable = 1 address = "[::]:8200" cluster_address = "[::]:8201" } storage "raft" { path = "/vault/data" } service_registration "kubernetes" {}Then deploy with Helm:
Command Linehelm upgrade --install vault hashicorp/vault -f values.custom.yaml
Unsealing vaults
Important: Save the unseal keys!
Command Linek exec vault-0 -it -- vault operator init # Run this three times, each with a different unseal key k exec vault-0 -it -- vault operator unseal
Setting up secrets engine
Configure the expected secrets engine for your application.
Command Linevault secrets enable -path={secretengine} kv
Enabling Kubernetes authentication
Setup BootConfig for eventual Kubernetes authentication. This can be done before cluster bring-up.
YAMLvault: url: "http://c3-vault-0.c3-vault-internal:8200", root: "mem:///secret/vault", vaultKind: "hashicorp", authKind: "kubernetes", role: "c3"
Configure Kubernetes Auth on Vault
Create a policy for the c3-server:
Command Linevault policy write c3 - <<EOF path "secret/*" { capabilities = [ "create", "read", "update", "delete", "list" ] } path "auth/*" { capabilities = [ "create", "read", "update", "list" ] } path "auth/token/renew-self" { capabilities = [ "deny" ] } EOFEnable Kubernetes authentication:
Command Linevault auth enable kubernetesGather necessary information to configure Kubernetes auth:
Command Line# Get secret token export JWT_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) # Get ca.crt export SA_CA_CRT=$(cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)Configure Kubernetes auth:
Command Linevault write auth/kubernetes/config \ kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \ token_reviewer_jwt="$JWT_TOKEN" \ kubernetes_ca_cert="$SA_CA_CRT"Configure the Kubernetes role:
Command Linevault write auth/kubernetes/role/c3 \ bound_service_account_names="c3" \ bound_service_account_namespaces="alan" \ token_policies="c3, default"
Configure HashiCorp Vault through the C3 Agentic AI Platform
The C3 Agentic AI Platform only supports key-value secrets engine for HashiCorp Vault. Further configurations for connecting
HashiCorp Vault to C3 Agentic AI Platform can be made by editing the BootConfig values. If the C3 Agentic AI Platform is hosted on Kubernetes, then BootConfig values must be changed using Helm. Otherwise, if C3 Agentic AI Platform is hosted locally, editing the BootConfig JSON file is sufficient.
Configure secrets engine
Secrets engine with the name secret is used by default in HashiCorp Vault. To specify the name of the secrets engine
that C3 Agentic AI Platform mounts config or vault to, the BootConfig should set the fields config/root orvault/root accordingly.
{
"type": "BootConfig",
"config": {
"root": "mem:///<new secrets engine>/config"
},
"vault": {
"root": "mem:///<new secrets engine>/vault"
}
}Configure mounts
C3 Agentic AI Platform also supports split storage of secret and non-secret config values. For example, non-secret values can be stored on C3 Agentic AI Platform supported ConfigStore , and secret values can be stored on Hashicorp's Vault. Alternatively, one can also choose to store both secret and non-secret values in a single mount, ex. Hashicorp's Vault only. Configuring this is done through the vaultKind field in BootConfig's config and vault fields.
Below is an example configuring non-secret config values to be stored on a ConfigStore mounted on local filesystem and secret config values to be stored on HashiCorp Vault.
{
"type": "BootConfig",
"config": {
"root" :"file:///usr/local/share/c3/v8/server/config"
},
"vault": {
"vaultKind": "hashicorp",
"root": "mem:///secret/vault"
}
}Below is an example configuring both secret and non-secret config values to be stored on HashiCorp Vault.
{
"type": "BootConfig",
"config": {
"vaultKind": "hashicorp",
"root": "mem:///secret/vault"
},
"vault": {
"vaultKind": "hashicorp",
"root": "mem:///secret/vault"
}
}Using Hashicorp Vault through the C3 Agentic AI Platform
The C3 Agentic AI Platform provides a set of APIs to interact with HashiCorp Vault through HashiCorpVault. These APIs are used to get, put, list and delete secrets.
HashiCorpVault.inst().put("secret/example/path", "{\"key1\": \"value1\", \"key2\": \"value2\"}")
HashiCorpVault.inst().get("secret/example/path")
HashiCorpVault.inst().list("secret/example")
HashiCorpVault.inst().delete("secret/example/path")There are also APIs to set and get custom metadata (setting null metadata is equivalent to deleting the metadata).
HashiCorpVault.inst().putCustomMetadata("secret/example/path", {"key": "value"})
HashiCorpVault.inst().getCustomMetadata("secret/example/path")If the BootConfig is configured with customMetadata, then all secrets will be automatically tagged with the custom metadata.