Skip to content

Commit 033ed63

Browse files
committed
ci: add protectjs for CI secrets management
Replace 1Password CLI with @cipherstash/protect (protectjs) for encrypting and decrypting CI secrets using ZeroKMS. - Add scripts/ directory with TypeScript encrypt/decrypt tooling - Add encrypted secrets file (.github/secrets.env.encrypted) - Update all workflow files to use protectjs decryption - Add scripts/node_modules/ to .gitignore Requires GitHub secrets: CS_VAULT_CLIENT_KEY, CS_VAULT_CLIENT_ACCESS_KEY
1 parent 2d436e1 commit 033ed63

File tree

11 files changed

+1165
-35
lines changed

11 files changed

+1165
-35
lines changed

.github/secrets.env.encrypted

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
{
2+
"CS_CLIENT_ACCESS_KEY": {
3+
"k": "ct",
4+
"c": "mBbLSVoU8`Do{H^4JdEH-DQ=;S0?!jXuj1GO<~nS77f6pGpQlROf9T!OWofsjl^#8A)M`97s6*4d0;YqiP5Q}aMyTySjc4-4673@C8B(NM?d)d7XuPf8JI)0vuk!)IKt`S^%ik$#2^`^r9+Nxb_`1Qo*(n?oS^3v|KZyn5qEtOAqksWikYQ$VQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
5+
"ob": null,
6+
"bf": null,
7+
"hm": null,
8+
"i": {
9+
"t": "ci_secrets",
10+
"c": "value"
11+
},
12+
"v": 2
13+
},
14+
"CS_CLIENT_ID": {
15+
"k": "ct",
16+
"c": "mBbLxa?ahrJW29+2tZu4UG$>FHmFEjiG510=YV<ZH5o@@I-JnG?;wSK_~l8m@bq$!_4U}2rXu}Z05wRbS!{&Gs!g$9G<a>qATlXu#AZ-+z)vGg7>@rO#&?Nyn#PyM+c#ggbfg(pF{O54Y;|SC5Hwu<&vtJ>^t3onC{{VkhX",
17+
"ob": null,
18+
"bf": null,
19+
"hm": null,
20+
"i": {
21+
"t": "ci_secrets",
22+
"c": "value"
23+
},
24+
"v": 2
25+
},
26+
"CS_CLIENT_KEY": {
27+
"k": "ct",
28+
"c": "mBbL8G4ax6h3T~Q?tDDf%8k~=0b-Ynl7J`f9<S}gEPQu%m@y2iRJq;o5C?v^cDKPsmHvE-(a9!FZ~HhScEwSUAYfYYu#;C|HfSra)}92@p#YZn*?2G}?R>4zJ0Z;L9{dMuI!X+A>=g&*voOs>;NFtYQ<31*#vAI^rYUd<p%(8aTLpW{wSJ0(yKO?p=$E-M_Job5{!X%iEcGZ}V@DO5y0YD;z(S2n1~SCN!mjvRwhTDCSsziHK-_LwTrwEK<ae%M<IdA?(of}{=<khZN^KqCIXX#eK?mkKF;+wlW_MjPGZ6*YZ%578;C8skTj^6#m10Om(Q+M^>(y>*0hkz{!b}eF^i`h<I#$<<Iv6p^j>bwxLEL_MYql(SEdej(3Y6`O$)10zct`!1(oaD2`A94cnf+8)Z+7SNee62O1DW2PGR<(>^3lWbgXMzq6XlbvZrg@l=cyD~(CNWUo((hawMLjb>x=PE#2{IEcyVS|$jr{D@^!2|R>_;<Vq|m<0N&4oQ%xWy=qIIiVQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
29+
"ob": null,
30+
"bf": null,
31+
"hm": null,
32+
"i": {
33+
"t": "ci_secrets",
34+
"c": "value"
35+
},
36+
"v": 2
37+
},
38+
"CS_WORKSPACE_CRN": {
39+
"k": "ct",
40+
"c": "mBbM11wMFh#K#zPwdM~;ju3FfG{A%7YOibQop2IN#?B!h8eK84igixM;ReqD(co=^a(~lA7uWP8T@&Gd64qf-Bn>wluEZeSgL3m3dI-49kfKlVJ2oJ>=6Nj?K<Z&m#1E1h5jT~kc42IFWyBCPT>Z~>Z$R|4I8P{6Im?F",
41+
"ob": null,
42+
"bf": null,
43+
"hm": null,
44+
"i": {
45+
"t": "ci_secrets",
46+
"c": "value"
47+
},
48+
"v": 2
49+
},
50+
"CS_DEFAULT_KEYSET_ID": {
51+
"k": "ct",
52+
"c": "mBbJss<&W}*cPMX<|8MC6Jz1THhfz?pMTD^N5K+iXDom=eL~KfZiZvZ?BX~^Cf)U7IxtS494>ot;NV9~V5`T>A085uF9AWsAR|;F|L`fBbduc_c0%;e8FE}^9C+I-6&+JSH%G}TPNjBXY;|SC5Hwu<&vtJ>^t3onC{{VkhX",
53+
"ob": null,
54+
"bf": null,
55+
"hm": null,
56+
"i": {
57+
"t": "ci_secrets",
58+
"c": "value"
59+
},
60+
"v": 2
61+
},
62+
"CS_TENANT_KEYSET_ID_1": {
63+
"k": "ct",
64+
"c": "mBbLxyC6xC+{EW;;5A`|u`KPxHUzKScK`B&^Jy}8?+{AvGOt<>3Ysz%{Twa+L!gXjsy63HTwS%&1712T=;=KzS_v)L5cf62AYUC~xJMlYv<xX{ZN^r0<9;QYPkWMvl=QLTzHfEYTcvhkY;|SC5Hwu<&vtJ>^t3onC{{VkhX",
65+
"ob": null,
66+
"bf": null,
67+
"hm": null,
68+
"i": {
69+
"t": "ci_secrets",
70+
"c": "value"
71+
},
72+
"v": 2
73+
},
74+
"CS_TENANT_KEYSET_ID_2": {
75+
"k": "ct",
76+
"c": "mBbMJ`*UJyfuK2WYIx}JeqCO~Ha*-O?bCvj0H4BWR!I{IP+g&84Z`0c?^?NS3pgN;u~y8WK){H*3!ky3h!n?FzrMcGlAh+oAZuER+rp|(n*Dxg^gF{wpz@sto!>QMQm6+&?wJE6GNpE5Y;|SC5Hwu<&vtJ>^t3onC{{VkhX",
77+
"ob": null,
78+
"bf": null,
79+
"hm": null,
80+
"i": {
81+
"t": "ci_secrets",
82+
"c": "value"
83+
},
84+
"v": 2
85+
},
86+
"CS_TENANT_KEYSET_ID_3": {
87+
"k": "ct",
88+
"c": "mBbLNuQ68uYA@n#p0N1{dBu*zHdE`M%fbp1-_?W4`AEXO*zc-@=O9><vX;ge`1kF3_H-1Sa}nxWT?6ss2+SoEJs(zXt|KhOAn&FMfI7lmP}}X|TUDIMCU<N$U+mgk1RTf2auY!*P^ETZY;|SC5Hwu<&vtJ>^t3onC{{VkhX",
89+
"ob": null,
90+
"bf": null,
91+
"hm": null,
92+
"i": {
93+
"t": "ci_secrets",
94+
"c": "value"
95+
},
96+
"v": 2
97+
},
98+
"CS_TENANT_KEYSET_NAME_1": {
99+
"k": "ct",
100+
"c": "mBbJ+K&~zqj~hA_s_brbV0D|s7Xp~0205UCF^xN;Ns7e=m`RWayps}t#2`?P9j09-zvbqOuavY5bnQx4PA1>4T;p_tY()ytR_vvAVQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
101+
"ob": null,
102+
"bf": null,
103+
"hm": null,
104+
"i": {
105+
"t": "ci_secrets",
106+
"c": "value"
107+
},
108+
"v": 2
109+
},
110+
"CS_TENANT_KEYSET_NAME_2": {
111+
"k": "ct",
112+
"c": "mBbL}WAbeTps@Mb2F2-O!$sZ17t=Cd3lu>!8?)(EBu0T<4=Esv8cRfl#2{-@)J9now;&lMqA$iiHUU)}y)=fkK>Ciy^P!vSvNxr6VQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
113+
"ob": null,
114+
"bf": null,
115+
"hm": null,
116+
"i": {
117+
"t": "ci_secrets",
118+
"c": "value"
119+
},
120+
"v": 2
121+
},
122+
"CS_TENANT_KEYSET_NAME_3": {
123+
"k": "ct",
124+
"c": "mBbJwjyTKdTw8=TdyJ9#EDfl{7w{Kl<PpWPX_UW3j&Sc3RyQMFYJuSr#2`E~L?Tk=XN`She%njse&wgIpn7u#m7^<}|C5dP9GazeVQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
125+
"ob": null,
126+
"bf": null,
127+
"hm": null,
128+
"i": {
129+
"t": "ci_secrets",
130+
"c": "value"
131+
},
132+
"v": 2
133+
},
134+
"DOCKER_HUB_USERNAME": {
135+
"k": "ct",
136+
"c": "mBbJx*gnX#oukxKVee&yAkZtsA>GGfJHd6wn21L&_@lHCm207NnPl&O{i{{7b!RG7K=s5RjVeiDiAPtDArSLa5ZE?t)<`)rh0?Hop1JJl`6(R?rFLO#b!Eg5G+h19c5guRv^Y;FRyoUu",
137+
"ob": null,
138+
"bf": null,
139+
"hm": null,
140+
"i": {
141+
"t": "ci_secrets",
142+
"c": "value"
143+
},
144+
"v": 2
145+
},
146+
"DOCKER_HUB_PASSWORD": {
147+
"k": "ct",
148+
"c": "mBbK*YbGjRbIEUJ;<LEUwmIp<I@ePaks(deqq%0Sf>l7IpaEQl3416=!<r_6Z}W;m#f;jB7XqPHYk|0|nB5PK(~V~iyGbRG>tEKyAXSugKRW6Htia|<mUj7BLgi3V^LwHGp_oxI<S7T2IHh)BY;|SC5Hwu<&vtJ>^t3onC{{VkhX",
149+
"ob": null,
150+
"bf": null,
151+
"hm": null,
152+
"i": {
153+
"t": "ci_secrets",
154+
"c": "value"
155+
},
156+
"v": 2
157+
},
158+
"MULTITUDES_ACCESS_TOKEN": {
159+
"k": "ct",
160+
"c": "mBbKHz&;-To())kJ?nL;PvuU<0e1LJPzQ$#7Ug-%n=uXD(aTAjP4{L_z#E(X;IhH9Q<Bom)9my&>C4Ym4b`KXe?Y)HqcJ>qx1<#@>U9Bta5E7qM~<xtb!3l$k1C(t$D>Hl4%fG<K?-2U_Jw9o2%6$)PEVsU<^1wCiFODx+jX@$#C3C4W$=2_=PGn==#0x>FNuIo^b_ng2^0#=te%aZNxV53-uVKMgDk<O@Q0j5RLnV*ZHG2}Vy{!aj+==H2MEOhPZv8PR`5-H4)`5uo^HS}LP&x{;?<hs1|7}(Ew*BE1s1H$j75|yFSp1kSfZN^RcCw+3%b1za}1iUBV?ew8UC1a+kTr&?HXitn?U1fTa+AdGdQ}BZsEww@dQRV?;SKnQn+#iAJ-4Oqku_z<i|Q1DvMV3yxY2#tM4=I7r|fl(z4naE24M&32=z*<^2;%GI86I9zO|*v>;~FQGNZ(=~w=mWqVKzEI57qi`6Q)&Rdk68I(64_I^sI#30&bs!?e8=@s6hiH|SuM<^&qZPXfHPmcrvuaUD*Be11*VQh6}#1J%G{m*u9K=iaYPbgM7%ZC",
161+
"ob": null,
162+
"bf": null,
163+
"hm": null,
164+
"i": {
165+
"t": "ci_secrets",
166+
"c": "value"
167+
},
168+
"v": 2
169+
}
170+
}

.github/workflows/benchmark.yml

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,39 @@ jobs:
2424
steps:
2525
- uses: actions/checkout@v4
2626
- uses: ./.github/actions/setup-test
27+
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: '20'
31+
cache: 'npm'
32+
cache-dependency-path: scripts/package-lock.json
33+
34+
- name: Install decrypt dependencies
35+
working-directory: scripts
36+
run: npm ci
37+
38+
- name: Decrypt secrets
39+
env:
40+
CS_CLIENT_KEY: ${{ secrets.CS_VAULT_CLIENT_KEY }}
41+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_VAULT_CLIENT_ACCESS_KEY }}
42+
run: cd scripts && npm run decrypt
43+
2744
- run: |
2845
mise run postgres:up --extra-args "--detach --wait"
46+
2947
- name: Run benchmark
3048
working-directory: tests/benchmark
3149
env:
32-
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
33-
CS_DEFAULT_KEYSET_ID: ${{ secrets.CS_DEFAULT_KEYSET_ID }}
34-
CS_CLIENT_ID: ${{ secrets.CS_CLIENT_ID }}
35-
CS_CLIENT_KEY: ${{ secrets.CS_CLIENT_KEY }}
36-
CS_WORKSPACE_CRN: ${{ secrets.CS_WORKSPACE_CRN }}
3750
RUST_BACKTRACE: "1"
3851
run: mise run benchmark:continuous
52+
3953
# Download previous benchmark result from cache (if exists)
4054
- name: Download previous benchmark data
4155
uses: actions/cache@v4
4256
with:
4357
path: ./cache
4458
key: ${{ runner.os }}-benchmark
59+
4560
# Run `github-action-benchmark` action
4661
- name: Store benchmark result
4762
uses: benchmark-action/github-action-benchmark@v1
@@ -56,10 +71,4 @@ jobs:
5671
comment-on-alert: true
5772
summary-always: true
5873
auto-push: true
59-
benchmark-data-dir-path: docs
60-
61-
- uses: ./.github/actions/send-slack-notification
62-
with:
63-
channel: engineering
64-
webhook_url: ${{ secrets.SLACK_NOTIFICATION_WEBHOOK_URL }}
65-
74+
benchmark-data-dir-path: docs

.github/workflows/release-aws-marketplace.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ jobs:
8282

8383
- uses: actions/checkout@v4
8484

85+
- uses: actions/setup-node@v4
86+
with:
87+
node-version: '20'
88+
cache: 'npm'
89+
cache-dependency-path: scripts/package-lock.json
90+
91+
- name: Install decrypt dependencies
92+
working-directory: scripts
93+
run: npm ci
94+
95+
- name: Decrypt secrets
96+
env:
97+
CS_CLIENT_KEY: ${{ secrets.CS_VAULT_CLIENT_KEY }}
98+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_VAULT_CLIENT_ACCESS_KEY }}
99+
run: cd scripts && npm run decrypt
100+
85101
- uses: jdx/mise-action@v2
86102
with:
87103
version: 2025.1.6 # [default: latest] mise version to install
@@ -111,6 +127,6 @@ jobs:
111127
--fail-with-body \
112128
--url "https://api.developer.multitudes.co/deployments" \
113129
--header "Content-Type: application/json" \
114-
--header "Authorization: ${{ secrets.MULTITUDES_ACCESS_TOKEN }}" \
130+
--header "Authorization: ${{ env.MULTITUDES_ACCESS_TOKEN }}" \
115131
--data '{"commitSha": "${{ github.sha }}", "environmentName":"marketplace"}'
116132

.github/workflows/release.yml

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ jobs:
2222
runs-on: ${{matrix.build.os}}
2323
steps:
2424
- uses: actions/checkout@v4
25+
26+
- uses: actions/setup-node@v4
27+
with:
28+
node-version: '20'
29+
cache: 'npm'
30+
cache-dependency-path: scripts/package-lock.json
31+
32+
- name: Install decrypt dependencies
33+
working-directory: scripts
34+
run: npm ci
35+
36+
- name: Decrypt secrets
37+
env:
38+
CS_CLIENT_KEY: ${{ secrets.CS_VAULT_CLIENT_KEY }}
39+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_VAULT_CLIENT_ACCESS_KEY }}
40+
run: cd scripts && npm run decrypt
41+
2542
- name: Setup Rust cache
2643
uses: Swatinem/rust-cache@v2
2744
if: github.event_name == 'pull_request' # only cache in pull requests
@@ -55,8 +72,8 @@ jobs:
5572
- name: Login to Docker Hub
5673
uses: docker/login-action@v3
5774
with:
58-
username: ${{ secrets.DOCKER_HUB_USERNAME }}
59-
password: ${{ secrets.DOCKER_HUB_PERSONAL_ACCESS_TOKEN }}
75+
username: ${{ env.DOCKER_HUB_USERNAME }}
76+
password: ${{ env.DOCKER_HUB_PASSWORD }}
6077

6178
- name: Set up Docker Buildx
6279
uses: docker/setup-buildx-action@v3
@@ -92,6 +109,24 @@ jobs:
92109
needs:
93110
- build
94111
steps:
112+
- uses: actions/checkout@v4
113+
114+
- uses: actions/setup-node@v4
115+
with:
116+
node-version: '20'
117+
cache: 'npm'
118+
cache-dependency-path: scripts/package-lock.json
119+
120+
- name: Install decrypt dependencies
121+
working-directory: scripts
122+
run: npm ci
123+
124+
- name: Decrypt secrets
125+
env:
126+
CS_CLIENT_KEY: ${{ secrets.CS_VAULT_CLIENT_KEY }}
127+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_VAULT_CLIENT_ACCESS_KEY }}
128+
run: cd scripts && npm run decrypt
129+
95130
- name: Download digests
96131
uses: actions/download-artifact@v4
97132
with:
@@ -102,8 +137,8 @@ jobs:
102137
- name: Login to Docker Hub
103138
uses: docker/login-action@v3
104139
with:
105-
username: ${{ secrets.DOCKER_HUB_USERNAME }}
106-
password: ${{ secrets.DOCKER_HUB_PERSONAL_ACCESS_TOKEN }}
140+
username: ${{ env.DOCKER_HUB_USERNAME }}
141+
password: ${{ env.DOCKER_HUB_PASSWORD }}
107142

108143
- name: Set up Docker Buildx
109144
uses: docker/setup-buildx-action@v3
@@ -135,5 +170,5 @@ jobs:
135170
--fail-with-body \
136171
--url "https://api.developer.multitudes.co/deployments" \
137172
--header "Content-Type: application/json" \
138-
--header "Authorization: ${{ secrets.MULTITUDES_ACCESS_TOKEN }}" \
173+
--header "Authorization: ${{ env.MULTITUDES_ACCESS_TOKEN }}" \
139174
--data '{"commitSha": "${{ github.sha }}", "environmentName":"dockerhub"}'

.github/workflows/test.yml

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,31 @@ jobs:
1818
steps:
1919
- uses: actions/checkout@v4
2020
- uses: ./.github/actions/setup-test
21+
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version: '20'
25+
cache: 'npm'
26+
cache-dependency-path: scripts/package-lock.json
27+
28+
- name: Install decrypt dependencies
29+
working-directory: scripts
30+
run: npm ci
31+
32+
- name: Decrypt secrets
33+
env:
34+
CS_CLIENT_KEY: ${{ secrets.CS_VAULT_CLIENT_KEY }}
35+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_VAULT_CLIENT_ACCESS_KEY }}
36+
run: cd scripts && npm run decrypt
37+
2138
- run: |
2239
mise run postgres:up --extra-args "--detach --wait"
23-
- env:
40+
41+
- name: Run tests
42+
env:
2443
# REMEMBER TO ADD ENVIRONMENT VARIABLES TO tests/docker-compose.yml
2544
# The tests/docker-compose.yml config passes the ENV vars into the container
26-
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
27-
CS_DEFAULT_KEYSET_ID: ${{ secrets.CS_DEFAULT_KEYSET_ID }}
28-
CS_TENANT_KEYSET_ID_1: ${{ secrets.CS_TENANT_KEYSET_ID_1 }}
29-
CS_TENANT_KEYSET_ID_2: ${{ secrets.CS_TENANT_KEYSET_ID_2 }}
30-
CS_TENANT_KEYSET_ID_3: ${{ secrets.CS_TENANT_KEYSET_ID_3 }}
31-
CS_TENANT_KEYSET_NAME_1: ${{ secrets.CS_TENANT_KEYSET_NAME_1 }}
32-
CS_TENANT_KEYSET_NAME_2: ${{ secrets.CS_TENANT_KEYSET_NAME_2 }}
33-
CS_TENANT_KEYSET_NAME_3: ${{ secrets.CS_TENANT_KEYSET_NAME_3 }}
34-
CS_CLIENT_ID: ${{ secrets.CS_CLIENT_ID }}
35-
CS_CLIENT_KEY: ${{ secrets.CS_CLIENT_KEY }}
36-
CS_WORKSPACE_CRN: ${{ secrets.CS_WORKSPACE_CRN }}
3745
RUST_BACKTRACE: "1"
3846
run: |
3947
mise run --output prefix test
4048
41-
- uses: ./.github/actions/send-slack-notification
42-
with:
43-
channel: engineering
44-
webhook_url: ${{ secrets.SLACK_NOTIFICATION_WEBHOOK_URL }}
45-

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ rust-toolchain.toml
1818
# credentials for local dev
1919
.env.proxy.docker
2020

21+
# CI secrets plaintext (never commit actual values)
22+
.github/secrets.env.plaintext
23+
24+
# Node modules (scripts directory)
25+
scripts/node_modules/
26+
2127
## benchmark result data
2228
tests/benchmark/results/*.csv
2329
tests/benchmark/benchmark-*.png

0 commit comments

Comments
 (0)