Skip to content

Commit 1ba81aa

Browse files
authored
feat(devel): enable vault persistence in dev mode (#2575)
Signed-off-by: Miguel Martinez <miguel@chainloop.dev>
1 parent 97925bb commit 1ba81aa

File tree

6 files changed

+190
-21
lines changed

6 files changed

+190
-21
lines changed

deployment/chainloop/Chart.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: Chainloop is an open source software supply chain control plane, a
77

88
type: application
99
# Bump the patch (not minor, not major) version on each change in the Chart Source code
10-
version: 1.307.0
10+
version: 1.307.1
1111
# Do not update appVersion, this is handled automatically by the release process
1212
appVersion: v1.60.0
1313

@@ -21,6 +21,7 @@ dependencies:
2121
name: postgresql
2222
repository: file://charts/postgresql
2323
version: 15.x.x
24+
# vault is run in development mode only in development
2425
- condition: development
2526
name: vault
2627
repository: file://charts/vault

deployment/chainloop/templates/_helpers.tpl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,7 @@ secretPrefix: {{ required "secret prefix required" .secretPrefix | quote }}
7474
vault:
7575
{{- if and $.Values.development (or (not .vault) not .vault.address) }}
7676
address: {{ printf "http://%s-server:8200" (include "chainloop.vault.fullname" $) | quote }}
77-
{{- if $tokenEnvVar }}
78-
token: {{ $tokenEnvVar | quote }}
79-
{{- else }}
80-
{{- required "VAULT_DEV_ROOT_TOKEN_ID environment variable is required when development mode is enabled" (index $.Values.vault.server.extraEnvVars "VAULT_DEV_ROOT_TOKEN_ID") }}
81-
{{- end }}
77+
token: {{ default "notasecret" $tokenEnvVar | quote }}
8278
{{- else if (required "vault backend selected but configuration not provided" .vault ) }}
8379
address: {{ required "vault address required" .vault.address | quote }}
8480
token: {{ required "vault token required" .vault.token | quote }}

deployment/chainloop/values.yaml

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,14 +1690,94 @@ postgresql:
16901690
## @param vault.server.extraEnvVars[1].name Address to listen on development mode
16911691
## @param vault.server.extraEnvVars[1].value The address to listen on. Default: [::]:8200
16921692
vault:
1693+
extraDeploy:
1694+
- |
1695+
apiVersion: v1
1696+
kind: ConfigMap
1697+
metadata:
1698+
name: {{ include "vault.server.fullname" . }}-init
1699+
namespace: {{ include "common.names.namespace" . | quote }}
1700+
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
1701+
app.kubernetes.io/part-of: vault
1702+
app.kubernetes.io/component: server
1703+
data:
1704+
vault-init.sh: |
1705+
#!/bin/sh
1706+
set -e
1707+
1708+
# Start Vault in background
1709+
vault server -config /bitnami/vault/config/config.hcl &
1710+
PID=$!
1711+
1712+
# Wait for Vault to start
1713+
echo "Waiting for Vault to start..."
1714+
until vault status > /dev/null 2>&1; STATUS=$?; [ $STATUS -eq 0 ] || [ $STATUS -eq 2 ]; do
1715+
sleep 1
1716+
done
1717+
1718+
export VAULT_ADDR='http://127.0.0.1:8200'
1719+
1720+
# Initialize if not already initialized or if init.txt is invalid
1721+
if [ ! -f /bitnami/vault/data/init.txt ] || ! grep -q "Unseal Key 1:" /bitnami/vault/data/init.txt; then
1722+
echo "Initializing Vault..."
1723+
vault operator init -key-shares=1 -key-threshold=1 > /bitnami/vault/data/init.txt
1724+
echo "Vault initialized successfully"
1725+
else
1726+
echo "Vault already initialized, using existing keys"
1727+
fi
1728+
1729+
# Unseal
1730+
echo "Reading unseal key..."
1731+
UNSEAL_KEY=$(grep 'Unseal Key 1:' /bitnami/vault/data/init.txt | awk '{print $NF}')
1732+
if [ -z "$UNSEAL_KEY" ]; then
1733+
echo "ERROR: Failed to read unseal key from init.txt"
1734+
echo "Contents of init.txt:"
1735+
cat /bitnami/vault/data/init.txt || echo "Cannot read init.txt"
1736+
exit 1
1737+
fi
1738+
echo "Unsealing Vault..."
1739+
vault operator unseal "$UNSEAL_KEY"
1740+
1741+
# Login
1742+
ROOT_TOKEN=$(grep 'Initial Root Token:' /bitnami/vault/data/init.txt | awk '{print $NF}')
1743+
export VAULT_TOKEN=$ROOT_TOKEN
1744+
1745+
# Create 'notasecret' token if it doesn't exist
1746+
if ! vault token lookup notasecret > /dev/null 2>&1; then
1747+
echo "Creating 'notasecret' token..."
1748+
vault token create -id="notasecret" -policy="root"
1749+
fi
1750+
1751+
# Enable KV v2 secrets engine (required by controlplane)
1752+
if ! vault secrets list | grep -q "^secret/"; then
1753+
echo "Enabling KV v2 secrets engine at secret/..."
1754+
vault secrets enable -path=secret kv-v2
1755+
else
1756+
echo "Secrets engine already exists at secret/"
1757+
fi
1758+
1759+
# Keep container running
1760+
wait $PID
16931761
server:
1694-
args: [
1695-
"server",
1696-
"-dev"
1697-
]
1698-
extraEnvVars:
1699-
- name: VAULT_DEV_ROOT_TOKEN_ID
1700-
value: "notasecret"
1701-
- name: VAULT_DEV_LISTEN_ADDRESS
1702-
value: "[::]:8200"
1703-
config: "storage \"inmem\" {}\ndisable_mlock = true\nui = true\nservice_registration \"kubernetes\" {}"
1762+
command: ["/vault-init.sh"]
1763+
args: [""]
1764+
config: |
1765+
disable_mlock = true
1766+
ui = false
1767+
listener "tcp" {
1768+
tls_disable = 1
1769+
address = "[::]:8200"
1770+
cluster_address = "[::]:8201"
1771+
}
1772+
storage "file" {
1773+
path = "/bitnami/vault/data"
1774+
}
1775+
extraVolumes:
1776+
- name: vault-init
1777+
configMap:
1778+
name: '{{ include "vault.server.fullname" . }}-init'
1779+
defaultMode: 0755
1780+
extraVolumeMounts:
1781+
- name: vault-init
1782+
mountPath: /vault-init.sh
1783+
subPath: vault-init.sh

devel/compose.common.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,25 @@ services:
1717
interval: 2s
1818
retries: 10
1919

20-
# in memory-only vault for development
21-
# note that secrets will get removed when the container is restarted
20+
# Vault with persistence for development
2221
vault:
2322
image: docker.io/vault:1.12.3
2423
cap_add:
2524
- IPC_LOCK
2625
ports:
2726
- 8200:8200
28-
environment:
29-
- VAULT_DEV_ROOT_TOKEN_ID=notasecret
27+
volumes:
28+
- ./vault-config.hcl:/vault/config/local.hcl
29+
- ./vault-init.sh:/vault-init.sh
30+
- vault_data:/vault/file
31+
command: "/vault-init.sh"
3032
healthcheck:
3133
test: [ "CMD", "wget", "--spider", "http://127.0.0.1:8200/v1/sys/health" ]
3234
interval: 10s
3335
timeout: 3s
3436
retries: 10
3537
start_period: 5s
38+
3639
volumes:
37-
postgresql_data:
40+
postgresql_data:
41+
vault_data:

devel/vault-config.hcl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#
2+
# Copyright 2025 The Chainloop Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
storage "file" {
17+
path = "/vault/file"
18+
}
19+
20+
listener "tcp" {
21+
address = "0.0.0.0:8200"
22+
tls_disable = 1
23+
}
24+
25+
disable_mlock = true
26+
ui = true

devel/vault-init.sh

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/sh
2+
#
3+
# Copyright 2025 The Chainloop Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -e
18+
19+
# Start Vault in background
20+
vault server -config=/vault/config/local.hcl &
21+
VAULT_PID=$!
22+
23+
# Wait for Vault to start
24+
sleep 2
25+
26+
export VAULT_ADDR='http://127.0.0.1:8200'
27+
28+
# Check if Vault is initialized
29+
if ! vault status | grep -q "Initialized.*true"; then
30+
echo "Initializing Vault..."
31+
vault operator init -key-shares=1 -key-threshold=1 > /vault/file/init.txt
32+
fi
33+
34+
# Unseal Vault
35+
echo "Unsealing Vault..."
36+
UNSEAL_KEY=$(grep "Unseal Key 1:" /vault/file/init.txt | awk '{print $4}')
37+
vault operator unseal $UNSEAL_KEY
38+
39+
# Login with root token to create the dev token
40+
ROOT_TOKEN=$(grep "Initial Root Token:" /vault/file/init.txt | awk '{print $4}')
41+
export VAULT_TOKEN=$ROOT_TOKEN
42+
43+
# Create the 'notasecret' token if it doesn't exist
44+
echo "Ensuring 'notasecret' token exists..."
45+
if ! vault token lookup notasecret > /dev/null 2>&1; then
46+
echo "Token 'notasecret' not found (or lookup failed), creating it..."
47+
vault token create -id="notasecret" -policy="root"
48+
else
49+
echo "Token 'notasecret' already exists."
50+
fi
51+
52+
# Enable KV v2 secrets engine at secret/ if not enabled
53+
if ! vault secrets list | grep -q "^secret/"; then
54+
echo "Enabling KV v2 secrets engine at secret/..."
55+
vault secrets enable -path=secret kv-v2
56+
else
57+
echo "Secrets engine already exists at secret/"
58+
fi
59+
60+
61+
# Keep container running
62+
wait $VAULT_PID

0 commit comments

Comments
 (0)