Skip to content

Commit 7b6ec28

Browse files
committed
🤖 consolidate github token refresh into single container
1 parent b26d155 commit 7b6ec28

File tree

2 files changed

+192
-9
lines changed

2 files changed

+192
-9
lines changed

flux/secrets/renovate-config.sops.yaml

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,70 @@ metadata:
55
namespace: renovate-system
66
type: Opaque
77
stringData:
8-
config.json: ENC[AES256_GCM,data:acyLXEKkYXvOo3yyA6kGspV8BAKP9tEyC1XjH6G7njYPMSZAl8wN0Si7z52GgFRPyeGA0FMAiKFlAu4jp7dozrG3oKxO///fYvVDztJLBVrxuJMH26IhFzpfgBYqEMjkdjhsNENW8u4zntAgin81i8RWEfgp6sGxTjpRikTI+oundLh/Wcxfagwa6suUqLYTxZFNOja5vhiNABo2JM8xSeWS7/iBv4TEF1wkw080EnxiH4PAYtQBOgGQGq8EGTTSPAq48j3hhheGTDy4j9HQ1hySVTfuGB2nK6KchFJpj6TUAbgBvSXFZYDlH6a/P/GC0o28NxWiXHhltxpCUVc8QptSq3trT1TQN7kAC9/leOmrZsidZtedmdg5CPcvr/p7kbD4EVQ/TCQ4/mdeD3aCkFAMpn9OiC1E+/ahwGBqVpLvY5aaaGYGqXu1tCVHZnXk+HwMlp5ViCWNSZL8nCUtAVCUdKjadp+5sUCQ6rmlpDEfTJwja+5Pw+ady9kn1zj3nj6FBb6NJt29z4Pdg6FHoztF8wfWHx8gFeTDjvClTUhnYqXQ+nfAz2VDta2UJGLm4h1Ko+9GSXPiRb7ARoRHvwu8FNKTjhk3Lo9nTYyp3Ri9ciwmJ7MDupZFI9mJT8dXP5lnvGVho/aXRjJUtVT9IKF2x8pQ882m5+7X4/07nIZfwmFqHSLieC9LrIuRm59YnBwtE2ctyFj8BbxpgRq7vy8hJPKb3e2v2tk=,iv:Q0dEB9E9KP4OPtG4vDkcrAWUUNrX/sSUki5oqZF0HVQ=,tag:3EafbL+gccCqY2KOQRywuA==,type:str]
9-
healthcheckUrl: ENC[AES256_GCM,data:Xrcj3Gaw55wUUxelFLGgWDXy9d8T4GsQ+6fyJGfx1HxcD2XRG9Kg/jQ5EW8sVY3K7NRm4Nmp4rs0vV2GPGDn/c/18W/5c1e9KP2t,iv:5VPcjd5Sx3C75nJAr0vCOEddigimloqRHgf4BGzgOi4=,tag:dHz83H6r8WERi9I8hzVG9Q==,type:str]
8+
config.json: ENC[AES256_GCM,data:OJy0K25m45r4ns+fehQsDS0/XbCRlZdIypnU+2nkFB8Lctm2RtrQ8ZeFj6wdADBPqi7HhFKWlsaKwQwoEqLHPTEXBsL0qSjGe4xCIqhadIS/zOuWE4NjF12jxVxuUKgDcjTpkbRTrjyn1IEqumh2f7mHtrKXjH33A0pj+GyNh/SFugq4b0liw5gnUyO1TtjJ6n0wylwpZtq2H5JWkkzQPRPh4GQDKBodCq7m7JaTvExzYGyzv+hq/++8p0s89+kkx61K5bRGaczn9jl0QgCWFDCrnY5R3EtoFQGgAj6lBUQi6Z5vi5CxuNRXbAJLoFUzbvdgaqcDhyPFtqmh47uT1g2kx7thnwkORuRNeQ/sT3w4Iml0XNQN2TmUQsEy7kkTWVYdccd6O7Av+lby4Zh9LZUygEKMiB4fUogVTNrF/GQX7Vc4aYLjOGU4kmrmrNuxuoiZRmT15gRBj3Uu3VsOb2QWPQm2HBJ5rdlnGXxw0hLVRkLMWFmQwopg4cJk0+QWOQwMT2gIagjpVc/rWohSrgcGV6ZzbOFWiCg2JJ/RjFUgoDZcrYH5Q8G+40Rs55uJtNXRH8ZugBuB2W++,iv:LqDBjbeq/dam78mUFNcrg/lUIw9V0FzwayMd3fdBtfs=,tag:Y7dwAah+XdNEcLa0a0V8Vg==,type:str]
9+
healthcheckUrl: ENC[AES256_GCM,data:jozdcJGhlts8DHOychFe/HN4EeRRZekN/hFQ+N01/Zh4X0kTk1tZYtNfD3BGmhLJ8yF0N2CSp2eQo8YwAUH770lsE/ilZtgZ3Gcx,iv:uKr1cS/BeWgBRdTHpDs/R7ND0v8q3bUycsLy3tdg7X0=,tag:BpOfopGmnviTGYe4LPMHsQ==,type:str]
1010
sops:
1111
age:
1212
- recipient: age168avplsha0pc878zkkgnx2n7zku0grgmwal2grmxjxnx579j9ffq0a0yfp
1313
enc: |
1414
-----BEGIN AGE ENCRYPTED FILE-----
15-
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBweWkyelowOEJsNFo1SjNx
16-
SmozdUY4VlVsVHFIZmxSdENGZG1VYW54VHp3Cnh2YS92c09SbnhQbXU5ODNMUWlQ
17-
UDFPaTZRaXViVm4xTDVhUjNYbmFHM2cKLS0tIEI5NVc1d3NnbG9GTnA3TmRrK0R2
18-
d1JtcXVxbGpXYldXQmlTazQrMFRQaVUKiYmXESiQF6rA+J+zC9ReGVFeiRBvvtGe
19-
WgAmZznt5qaeXiOfh38iVqt6bY4q/1pPSaPHXJxd6jXIX+SsbX0MlA==
15+
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWS05Jbjd4WFU3VTM1WURu
16+
eDUwNWRlM29INlQyWFdXUUtpUCthNHFmc2ljCnRpalo2b3o1bEg4OWtRYXEwNjNI
17+
aFJIbk4yZkV2STZ4ZWVnQ3loSVZBSUkKLS0tIDdyaTlDZW1Yb3FQV2M3QWRCcDFr
18+
UlVPbzFncjVVa0ZVRVpaRFRaeGFuQlUKS0RjsbiCyCnfWNZi8j8/jkE2rQi6m/b6
19+
cpaMCF/VgCVata9riXeK5X4n944GAtGBPsr2VVVYD0ry8ME82bWd6Q==
2020
-----END AGE ENCRYPTED FILE-----
21-
lastmodified: "2025-04-11T11:21:34Z"
22-
mac: ENC[AES256_GCM,data:FdRluyVXWMUlI3ktp2bTiEJZg9mUCX37m9wU4Q/0g0X9M/QEwcNVsoAMRsg2YY1S943GoHUn/3zLeoxqIaTptGETHirrAtej+HcPvjNqq7QA74WvcFThrH9wTPat9uPWk+RAxYiLlbGUhBlQBXFV2fHr6529gn5OxH3OkJmqalA=,iv:FGMbG1CgSAg7Wg+if+6ZIfMIFO/jV2mP/a8COmwZTMY=,tag:xBRsgwjHNWUvUncTfrfswg==,type:str]
21+
lastmodified: "2025-04-14T16:39:17Z"
22+
mac: ENC[AES256_GCM,data:32bgtu5VmZdb5heuqflvEiMihTmT/TfEuA1Sfb9TbF4Vm6EQkrcdstKJQSj3Mw2ucrC7o+Tw4dc+ZwwZUPPTQ5CapBQDoEwtT9piAk9Bgp/8ZPiFBylrs8FaxeODwNmN+wsn+5FObK39VK5E9mcy0BVOT/vrb9EDEpCXPmRhLy4=,iv:F3UOoiJMyZg90ac0rbpigFZvztyYAyhlbdMC1TnI6mA=,tag:qCRzttaYrNa4mLw4ty3tSA==,type:str]
23+
unencrypted_regex: ^(apiVersion|kind|metadata|type)$
24+
version: 3.10.1
25+
---
26+
apiVersion: v1
27+
kind: Secret
28+
metadata:
29+
name: renovate-github-token-secrets
30+
namespace: renovate-system
31+
type: Opaque
32+
stringData:
33+
CLIENT_ID: ENC[AES256_GCM,data:la6Zo52OfXSNWXzWNZ4l1w25T+Y=,iv:Fk0LTxFCvV8VJBcMTrcltehO1ssAdgQqlMzFhZdLI30=,tag:UYOlXsnAMpZ6a2lHhD4vig==,type:str]
34+
INSTALLATION_ID: ENC[AES256_GCM,data:yxb3VWWAYnE=,iv:KEdeXPYB80ubUcGi+KcGlFUQtATMA5waZkTPwLjFVy0=,tag:DmiyLBncqY5AIGxyeckynw==,type:str]
35+
healthcheckUrl: ENC[AES256_GCM,data:IFODGAggK9lY/usf7iBQtt//PaEcwbCF5k48imYdBsUYLALgk1hmeVm1IKZg3xihQMeMrfmYVn/+2rkwx+V4oymhEXwX67P1BsWm,iv:96BpQFm9NC/xfIY8Ds/ZRBQinNBQ2OQm34UzhujJ1JE=,tag:04DND3sdh3r+waYLt/hJHQ==,type:str]
36+
sops:
37+
age:
38+
- recipient: age168avplsha0pc878zkkgnx2n7zku0grgmwal2grmxjxnx579j9ffq0a0yfp
39+
enc: |
40+
-----BEGIN AGE ENCRYPTED FILE-----
41+
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWS05Jbjd4WFU3VTM1WURu
42+
eDUwNWRlM29INlQyWFdXUUtpUCthNHFmc2ljCnRpalo2b3o1bEg4OWtRYXEwNjNI
43+
aFJIbk4yZkV2STZ4ZWVnQ3loSVZBSUkKLS0tIDdyaTlDZW1Yb3FQV2M3QWRCcDFr
44+
UlVPbzFncjVVa0ZVRVpaRFRaeGFuQlUKS0RjsbiCyCnfWNZi8j8/jkE2rQi6m/b6
45+
cpaMCF/VgCVata9riXeK5X4n944GAtGBPsr2VVVYD0ry8ME82bWd6Q==
46+
-----END AGE ENCRYPTED FILE-----
47+
lastmodified: "2025-04-14T16:39:17Z"
48+
mac: ENC[AES256_GCM,data:32bgtu5VmZdb5heuqflvEiMihTmT/TfEuA1Sfb9TbF4Vm6EQkrcdstKJQSj3Mw2ucrC7o+Tw4dc+ZwwZUPPTQ5CapBQDoEwtT9piAk9Bgp/8ZPiFBylrs8FaxeODwNmN+wsn+5FObK39VK5E9mcy0BVOT/vrb9EDEpCXPmRhLy4=,iv:F3UOoiJMyZg90ac0rbpigFZvztyYAyhlbdMC1TnI6mA=,tag:qCRzttaYrNa4mLw4ty3tSA==,type:str]
49+
unencrypted_regex: ^(apiVersion|kind|metadata|type)$
50+
version: 3.10.1
51+
---
52+
apiVersion: v1
53+
kind: Secret
54+
metadata:
55+
name: renovate-github-token-key
56+
namespace: renovate-system
57+
type: Opaque
58+
stringData:
59+
private-key.pem: ENC[AES256_GCM,data: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,iv:NByP/ygjQVfzqLId9UdqiH5t7fnOQgrAAx+gskNfr+s=,tag:maujvCf4nPb489GdAKaaxA==,type:str]
60+
sops:
61+
age:
62+
- recipient: age168avplsha0pc878zkkgnx2n7zku0grgmwal2grmxjxnx579j9ffq0a0yfp
63+
enc: |
64+
-----BEGIN AGE ENCRYPTED FILE-----
65+
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWS05Jbjd4WFU3VTM1WURu
66+
eDUwNWRlM29INlQyWFdXUUtpUCthNHFmc2ljCnRpalo2b3o1bEg4OWtRYXEwNjNI
67+
aFJIbk4yZkV2STZ4ZWVnQ3loSVZBSUkKLS0tIDdyaTlDZW1Yb3FQV2M3QWRCcDFr
68+
UlVPbzFncjVVa0ZVRVpaRFRaeGFuQlUKS0RjsbiCyCnfWNZi8j8/jkE2rQi6m/b6
69+
cpaMCF/VgCVata9riXeK5X4n944GAtGBPsr2VVVYD0ry8ME82bWd6Q==
70+
-----END AGE ENCRYPTED FILE-----
71+
lastmodified: "2025-04-14T16:39:17Z"
72+
mac: ENC[AES256_GCM,data:32bgtu5VmZdb5heuqflvEiMihTmT/TfEuA1Sfb9TbF4Vm6EQkrcdstKJQSj3Mw2ucrC7o+Tw4dc+ZwwZUPPTQ5CapBQDoEwtT9piAk9Bgp/8ZPiFBylrs8FaxeODwNmN+wsn+5FObK39VK5E9mcy0BVOT/vrb9EDEpCXPmRhLy4=,iv:F3UOoiJMyZg90ac0rbpigFZvztyYAyhlbdMC1TnI6mA=,tag:qCRzttaYrNa4mLw4ty3tSA==,type:str]
2373
unencrypted_regex: ^(apiVersion|kind|metadata|type)$
2474
version: 3.10.1

flux/system/app-controllers/renovate.yaml

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,136 @@ spec:
3030
envList:
3131
- name: LOG_LEVEL
3232
value: debug
33+
- name: RENOVATE_TOKEN
34+
valueFrom:
35+
secretKeyRef:
36+
name: renovate-github-token
37+
key: RENOVATE_TOKEN
38+
---
39+
apiVersion: helm.toolkit.fluxcd.io/v2
40+
kind: HelmRelease
41+
metadata:
42+
name: renovate-github-token-refresher
43+
namespace: renovate-system
44+
spec:
45+
interval: 1m
46+
chart:
47+
spec:
48+
chart: app-template
49+
version: 3.7.3
50+
sourceRef:
51+
kind: HelmRepository
52+
name: bjw-s
53+
namespace: flux-system
54+
values:
55+
controllers:
56+
main:
57+
type: cronjob
58+
cronjob:
59+
schedule: "*/45 * * * *"
60+
concurrencyPolicy: Replace
61+
annotations:
62+
healthcheckUrlSecret: renovate-github-token-secrets
63+
containers:
64+
main:
65+
image:
66+
repository: ghcr.io/anokfireball/base-image
67+
tag: 3.21.3@sha256:0e6a0cae53fd35678d16e8faf18336871396c6e74dde13fa8896a76e1a8c6d83
68+
envFrom:
69+
- secret: renovate-github-token-secrets
70+
command: ["/bin/bash", "/scripts/token.sh"]
71+
args: ["$(CLIENT_ID)", "/key/private-key.pem", "$(INSTALLATION_ID)"]
72+
securityContext:
73+
runAsUser: 65534
74+
runAsGroup: 65534
75+
runAsNonRoot: true
76+
allowPrivilegeEscalation: false
77+
readOnlyRootFilesystem: true
78+
capabilities:
79+
drop:
80+
- ALL
81+
serviceAccount:
82+
create: true
83+
name: renovate-github-token-refresher
84+
rbac:
85+
roles:
86+
config-patcher:
87+
enabled: true
88+
type: Role
89+
rules:
90+
- apiGroups: [""]
91+
resources: ["secrets"]
92+
resourceNames: ["renovate-github-token"]
93+
verbs: ["get", "patch"]
94+
bindings:
95+
renovate-github-token-refresher:
96+
enabled: true
97+
type: RoleBinding
98+
roleRef:
99+
name: renovate-github-token-refresher-config-patcher
100+
kind: Role
101+
subjects:
102+
- kind: ServiceAccount
103+
name: renovate-github-token-refresher
104+
namespace: renovate-system
105+
configMaps:
106+
scripts:
107+
data:
108+
# https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app
109+
token.sh: |
110+
#!/usr/bin/env bash
111+
set -o pipefail
112+
113+
CLIENT_ID=$1 # Client ID as first argument
114+
115+
PEM=$( cat $2 ) # file path of the private key as second argument
116+
117+
NOW=$(date +%s)
118+
IAT=$(($NOW - 60)) # Issues 60 seconds in the past
119+
EXP=$(($NOW + 300)) # Expires 5 minutes in the future
120+
121+
b64enc() { openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'; }
122+
123+
HEADER_JSON='{
124+
"typ":"JWT",
125+
"alg":"RS256"
126+
}'
127+
# Header encode
128+
HEADER=$( echo -n "$HEADER_JSON" | b64enc )
129+
130+
PAYLOAD_JSON="{
131+
\"iat\":$IAT,
132+
\"exp\":$EXP,
133+
\"iss\":\"$CLIENT_ID\"
134+
}"
135+
# Payload encode
136+
PAYLOAD=$( echo -n "$PAYLOAD_JSON" | b64enc )
137+
138+
# Signature
139+
HEADER_PAYLOAD="$HEADER"."$PAYLOAD"
140+
SIGNATURE=$(
141+
openssl dgst -sha256 -sign <(echo -n "$PEM") \
142+
<(echo -n "$HEADER_PAYLOAD") | b64enc
143+
)
144+
145+
# Create JWT
146+
JWT="$HEADER_PAYLOAD"."$SIGNATURE"
147+
148+
TOKEN=$(curl --request POST \
149+
--url "https://api.github.com/app/installations/$3/access_tokens" \
150+
--header "Accept: application/vnd.github+json" \
151+
--header "Authorization: Bearer $JWT" \
152+
--header "X-GitHub-Api-Version: 2022-11-28" \
153+
| jq -r '.token')
154+
155+
kubectl patch secret renovate-github-token -n renovate-system --type='json' \
156+
-p='[{"op": "replace", "path": "/data/RENOVATE_TOKEN", "value":"'$(echo -n "$TOKEN" | base64)'"}]'
157+
persistence:
158+
token:
159+
type: emptyDir
160+
scripts:
161+
type: configMap
162+
name: renovate-github-token-refresher-scripts
163+
key:
164+
type: secret
165+
name: renovate-github-token-key

0 commit comments

Comments
 (0)