Skip to content

feat(secops): deploy talosctl-oidc for Pocket-ID authenticated read-only Talos access - #8912

Draft
tyriis wants to merge 1 commit into
mainfrom
feature/talos-oidc-readonly
Draft

feat(secops): deploy talosctl-oidc for Pocket-ID authenticated read-only Talos access#8912
tyriis wants to merge 1 commit into
mainfrom
feature/talos-oidc-readonly

Conversation

@tyriis

@tyriis tyriis commented May 24, 2026

Copy link
Copy Markdown
Owner

Draft PR for implementing Talos OIDC read-only access via Pocket-ID.

Changes

New: talosctl-oidc deployment (main + utility clusters)

  • bjw-s app-template HelmRelease with talosctl-oidc-server
  • ExternalSecret pulling Talos API CA from OpenBao
  • LoadBalancer Service (Cilium L2, IP pool 192.168.100.200-250)
  • Health probes, Reloader annotation, read-only root FS

Pocket-ID OIDC client

Manual steps remaining

  1. Create the Pocket-ID OIDC client via terraform-pocket-id
  2. Extract Talos API CA from each cluster and store in OpenBao
  3. Store client_id in OpenBao alongside CA
  4. Deploy and verify

Ref:

@tyriis-automation

tyriis-automation Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

main (kustomization) - 2026-05-24 22:44:59 UTC

--- kubernetes/main/apps Kustomization: flux-system/flux-apps Kustomization: secops/talosctl-oidc

+++ kubernetes/main/apps Kustomization: flux-system/flux-apps Kustomization: secops/talosctl-oidc

@@ -0,0 +1,28 @@

+---
+apiVersion: kustomize.toolkit.fluxcd.io/v1
+kind: Kustomization
+metadata:
+  labels:
+    kustomize.toolkit.fluxcd.io/name: flux-apps
+    kustomize.toolkit.fluxcd.io/namespace: flux-system
+  name: talosctl-oidc
+  namespace: secops
+spec:
+  commonMetadata:
+    labels:
+      app.kubernetes.io/name: talosctl-oidc
+  dependsOn:
+  - name: external-secrets-stores
+    namespace: secops
+  interval: 30m
+  path: ./kubernetes/main/apps/secops/talosctl-oidc/app
+  prune: true
+  retryInterval: 1m
+  sourceRef:
+    kind: GitRepository
+    name: flux-system
+    namespace: flux-system
+  targetNamespace: secops
+  timeout: 5m
+  wait: true
+
--- kubernetes/main/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc ExternalSecret: secops/talosctl-oidc-ca

+++ kubernetes/main/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc ExternalSecret: secops/talosctl-oidc-ca

@@ -0,0 +1,27 @@

+---
+apiVersion: external-secrets.io/v1
+kind: ExternalSecret
+metadata:
+  labels:
+    app.kubernetes.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/namespace: secops
+  name: talosctl-oidc-ca
+  namespace: secops
+spec:
+  dataFrom:
+  - extract:
+      key: infra/kubernetes/main/secops/talosctl-oidc
+  refreshInterval: 5m
+  secretStoreRef:
+    kind: ClusterSecretStore
+    name: openbao-backend
+  target:
+    creationPolicy: Owner
+    name: talosctl-oidc-ca
+    template:
+      data:
+        ca.crt: '{{ .ca_crt }}'
+        ca.key: '{{ .ca_key }}'
+      engineVersion: v2
+
--- kubernetes/main/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc HelmRelease: secops/talosctl-oidc

+++ kubernetes/main/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc HelmRelease: secops/talosctl-oidc

@@ -0,0 +1,113 @@

+---
+apiVersion: helm.toolkit.fluxcd.io/v2
+kind: HelmRelease
+metadata:
+  labels:
+    app.kubernetes.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/namespace: secops
+  name: talosctl-oidc
+  namespace: secops
+spec:
+  chart:
+    spec:
+      chart: app-template
+      sourceRef:
+        kind: HelmRepository
+        name: bjw-s-charts
+        namespace: flux-system
+      version: 5.0.1
+  install:
+    remediation:
+      retries: -1
+  interval: 30m
+  uninstall:
+    keepHistory: false
+  upgrade:
+    cleanupOnFail: true
+    remediation:
+      retries: 3
+  values:
+    controllers:
+      talosctl-oidc:
+        annotations:
+          reloader.stakater.com/auto: 'true'
+        containers:
+          app:
+            command:
+            - /talosctl-oidc
+            - serve
+            env:
+              TALOSCTL_OIDC_CA_CERT: /config/ca.crt
+              TALOSCTL_OIDC_CA_KEY: /config/ca.key
+              TALOSCTL_OIDC_CERT_TTL: 60m
+              TALOSCTL_OIDC_CLIENT_ID: <CLIENT_ID>
+              TALOSCTL_OIDC_DATA_DIR: /data
+              TALOSCTL_OIDC_ENDPOINTS: 192.168.100.101,192.168.100.102,192.168.100.103
+              TALOSCTL_OIDC_ISSUER_URL: https://id.techtales.io
+              TALOSCTL_OIDC_LISTEN: :8443
+              TALOSCTL_OIDC_ROLES: os:reader
+            image:
+              repository: ghcr.io/qjoly/talosctl-oidc-server
+              tag: 0.0.4@sha256:ff55155e0f0af646239815bc3e015cb22cfaf05472b0a5e58dc8c22b12a60baa
+            ports:
+            - containerPort: 8443
+              name: https
+            probes:
+              liveness:
+                custom: true
+                enabled: true
+                spec:
+                  httpGet:
+                    path: /healthz
+                    port: 8443
+              readiness:
+                custom: true
+                enabled: true
+                spec:
+                  httpGet:
+                    path: /healthz
+                    port: 8443
+            resources:
+              requests:
+                cpu: 10m
+                memory: 32Mi
+            securityContext:
+              allowPrivilegeEscalation: false
+              capabilities:
+                drop:
+                - ALL
+              readOnlyRootFilesystem: true
+              runAsNonRoot: true
+        pod:
+          securityContext:
+            runAsGroup: 65534
+            runAsNonRoot: true
+            runAsUser: 65534
+        replicas: 1
+        strategy: Recreate
+    defaultPodOptions:
+      securityContext:
+        fsGroup: 65534
+        fsGroupChangePolicy: OnRootMismatch
+    global:
+      createDefaultServiceAccount: false
+    persistence:
+      config:
+        globalMounts:
+        - path: /config
+          readOnly: true
+        name: talosctl-oidc-ca
+        type: secret
+      data:
+        globalMounts:
+        - path: /data
+        type: emptyDir
+    service:
+      app:
+        controller: talosctl-oidc
+        ports:
+          https:
+            port: 8443
+        type: LoadBalancer
+

@tyriis-automation

tyriis-automation Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

utility (helmrelease) - 2026-05-24 22:44:42 UTC

--- HelmRelease: secops/talosctl-oidc Service: secops/talosctl-oidc

+++ HelmRelease: secops/talosctl-oidc Service: secops/talosctl-oidc

@@ -0,0 +1,23 @@

+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: talosctl-oidc
+  labels:
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: talosctl-oidc
+    app.kubernetes.io/service: talosctl-oidc
+  namespace: secops
+spec:
+  type: LoadBalancer
+  ports:
+  - port: 8443
+    targetPort: 8443
+    protocol: TCP
+    name: https
+  selector:
+    app.kubernetes.io/controller: talosctl-oidc
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/name: talosctl-oidc
+
--- HelmRelease: secops/talosctl-oidc Deployment: secops/talosctl-oidc

+++ HelmRelease: secops/talosctl-oidc Deployment: secops/talosctl-oidc

@@ -0,0 +1,101 @@

+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: talosctl-oidc
+  labels:
+    app.kubernetes.io/controller: talosctl-oidc
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: talosctl-oidc
+  annotations:
+    reloader.stakater.com/auto: 'true'
+  namespace: secops
+spec:
+  revisionHistoryLimit: 3
+  replicas: 1
+  strategy:
+    type: Recreate
+  selector:
+    matchLabels:
+      app.kubernetes.io/controller: talosctl-oidc
+      app.kubernetes.io/name: talosctl-oidc
+      app.kubernetes.io/instance: talosctl-oidc
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/controller: talosctl-oidc
+        app.kubernetes.io/instance: talosctl-oidc
+        app.kubernetes.io/name: talosctl-oidc
+    spec:
+      enableServiceLinks: false
+      serviceAccountName: default
+      automountServiceAccountToken: false
+      securityContext:
+        runAsGroup: 65534
+        runAsNonRoot: true
+        runAsUser: 65534
+      hostIPC: false
+      hostNetwork: false
+      hostPID: false
+      dnsPolicy: ClusterFirst
+      containers:
+      - command:
+        - /talosctl-oidc
+        - serve
+        env:
+        - name: TALOSCTL_OIDC_CA_CERT
+          value: /config/ca.crt
+        - name: TALOSCTL_OIDC_CA_KEY
+          value: /config/ca.key
+        - name: TALOSCTL_OIDC_CERT_TTL
+          value: 60m
+        - name: TALOSCTL_OIDC_CLIENT_ID
+          value: <CLIENT_ID>
+        - name: TALOSCTL_OIDC_DATA_DIR
+          value: /data
+        - name: TALOSCTL_OIDC_ENDPOINTS
+          value: 192.168.100.31
+        - name: TALOSCTL_OIDC_ISSUER_URL
+          value: https://id.techtales.io
+        - name: TALOSCTL_OIDC_LISTEN
+          value: :8443
+        - name: TALOSCTL_OIDC_ROLES
+          value: os:reader
+        image: ghcr.io/qjoly/talosctl-oidc-server:0.0.4@sha256:ff55155e0f0af646239815bc3e015cb22cfaf05472b0a5e58dc8c22b12a60baa
+        livenessProbe:
+          httpGet:
+            path: /healthz
+            port: 8443
+        name: app
+        ports:
+        - containerPort: 8443
+          name: https
+        readinessProbe:
+          httpGet:
+            path: /healthz
+            port: 8443
+        resources:
+          requests:
+            cpu: 10m
+            memory: 32Mi
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          readOnlyRootFilesystem: true
+          runAsNonRoot: true
+        volumeMounts:
+        - mountPath: /config
+          name: config
+          readOnly: true
+        - mountPath: /data
+          name: data
+      volumes:
+      - name: config
+        secret:
+          secretName: talosctl-oidc-ca
+      - emptyDir: {}
+        name: data
+

@tyriis-automation

tyriis-automation Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

main (helmrelease) - 2026-05-24 22:45:00 UTC

--- HelmRelease: secops/talosctl-oidc Service: secops/talosctl-oidc

+++ HelmRelease: secops/talosctl-oidc Service: secops/talosctl-oidc

@@ -0,0 +1,23 @@

+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: talosctl-oidc
+  labels:
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: talosctl-oidc
+    app.kubernetes.io/service: talosctl-oidc
+  namespace: secops
+spec:
+  type: LoadBalancer
+  ports:
+  - port: 8443
+    targetPort: 8443
+    protocol: TCP
+    name: https
+  selector:
+    app.kubernetes.io/controller: talosctl-oidc
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/name: talosctl-oidc
+
--- HelmRelease: secops/talosctl-oidc Deployment: secops/talosctl-oidc

+++ HelmRelease: secops/talosctl-oidc Deployment: secops/talosctl-oidc

@@ -0,0 +1,101 @@

+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: talosctl-oidc
+  labels:
+    app.kubernetes.io/controller: talosctl-oidc
+    app.kubernetes.io/instance: talosctl-oidc
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: talosctl-oidc
+  annotations:
+    reloader.stakater.com/auto: 'true'
+  namespace: secops
+spec:
+  revisionHistoryLimit: 3
+  replicas: 1
+  strategy:
+    type: Recreate
+  selector:
+    matchLabels:
+      app.kubernetes.io/controller: talosctl-oidc
+      app.kubernetes.io/name: talosctl-oidc
+      app.kubernetes.io/instance: talosctl-oidc
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/controller: talosctl-oidc
+        app.kubernetes.io/instance: talosctl-oidc
+        app.kubernetes.io/name: talosctl-oidc
+    spec:
+      enableServiceLinks: false
+      serviceAccountName: default
+      automountServiceAccountToken: false
+      securityContext:
+        runAsGroup: 65534
+        runAsNonRoot: true
+        runAsUser: 65534
+      hostIPC: false
+      hostNetwork: false
+      hostPID: false
+      dnsPolicy: ClusterFirst
+      containers:
+      - command:
+        - /talosctl-oidc
+        - serve
+        env:
+        - name: TALOSCTL_OIDC_CA_CERT
+          value: /config/ca.crt
+        - name: TALOSCTL_OIDC_CA_KEY
+          value: /config/ca.key
+        - name: TALOSCTL_OIDC_CERT_TTL
+          value: 60m
+        - name: TALOSCTL_OIDC_CLIENT_ID
+          value: <CLIENT_ID>
+        - name: TALOSCTL_OIDC_DATA_DIR
+          value: /data
+        - name: TALOSCTL_OIDC_ENDPOINTS
+          value: 192.168.100.101,192.168.100.102,192.168.100.103
+        - name: TALOSCTL_OIDC_ISSUER_URL
+          value: https://id.techtales.io
+        - name: TALOSCTL_OIDC_LISTEN
+          value: :8443
+        - name: TALOSCTL_OIDC_ROLES
+          value: os:reader
+        image: ghcr.io/qjoly/talosctl-oidc-server:0.0.4@sha256:ff55155e0f0af646239815bc3e015cb22cfaf05472b0a5e58dc8c22b12a60baa
+        livenessProbe:
+          httpGet:
+            path: /healthz
+            port: 8443
+        name: app
+        ports:
+        - containerPort: 8443
+          name: https
+        readinessProbe:
+          httpGet:
+            path: /healthz
+            port: 8443
+        resources:
+          requests:
+            cpu: 10m
+            memory: 32Mi
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          readOnlyRootFilesystem: true
+          runAsNonRoot: true
+        volumeMounts:
+        - mountPath: /config
+          name: config
+          readOnly: true
+        - mountPath: /data
+          name: data
+      volumes:
+      - name: config
+        secret:
+          secretName: talosctl-oidc-ca
+      - emptyDir: {}
+        name: data
+

@tyriis-automation

tyriis-automation Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

utility (kustomization) - 2026-05-24 22:44:42 UTC

--- kubernetes/utility/apps Kustomization: flux-system/flux-apps Kustomization: secops/talosctl-oidc

+++ kubernetes/utility/apps Kustomization: flux-system/flux-apps Kustomization: secops/talosctl-oidc

@@ -0,0 +1,28 @@

+---
+apiVersion: kustomize.toolkit.fluxcd.io/v1
+kind: Kustomization
+metadata:
+  labels:
+    kustomize.toolkit.fluxcd.io/name: flux-apps
+    kustomize.toolkit.fluxcd.io/namespace: flux-system
+  name: talosctl-oidc
+  namespace: secops
+spec:
+  commonMetadata:
+    labels:
+      app.kubernetes.io/name: talosctl-oidc
+  dependsOn:
+  - name: external-secrets-stores
+    namespace: secops
+  interval: 30m
+  path: ./kubernetes/utility/apps/secops/talosctl-oidc/app
+  prune: true
+  retryInterval: 1m
+  sourceRef:
+    kind: GitRepository
+    name: flux-system
+    namespace: flux-system
+  targetNamespace: secops
+  timeout: 5m
+  wait: true
+
--- kubernetes/utility/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc ExternalSecret: secops/talosctl-oidc-ca

+++ kubernetes/utility/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc ExternalSecret: secops/talosctl-oidc-ca

@@ -0,0 +1,27 @@

+---
+apiVersion: external-secrets.io/v1
+kind: ExternalSecret
+metadata:
+  labels:
+    app.kubernetes.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/namespace: secops
+  name: talosctl-oidc-ca
+  namespace: secops
+spec:
+  dataFrom:
+  - extract:
+      key: infra/kubernetes/utility/secops/talosctl-oidc
+  refreshInterval: 5m
+  secretStoreRef:
+    kind: ClusterSecretStore
+    name: openbao-backend
+  target:
+    creationPolicy: Owner
+    name: talosctl-oidc-ca
+    template:
+      data:
+        ca.crt: '{{ .ca_crt }}'
+        ca.key: '{{ .ca_key }}'
+      engineVersion: v2
+
--- kubernetes/utility/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc HelmRelease: secops/talosctl-oidc

+++ kubernetes/utility/apps/secops/talosctl-oidc/app Kustomization: secops/talosctl-oidc HelmRelease: secops/talosctl-oidc

@@ -0,0 +1,113 @@

+---
+apiVersion: helm.toolkit.fluxcd.io/v2
+kind: HelmRelease
+metadata:
+  labels:
+    app.kubernetes.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/name: talosctl-oidc
+    kustomize.toolkit.fluxcd.io/namespace: secops
+  name: talosctl-oidc
+  namespace: secops
+spec:
+  chart:
+    spec:
+      chart: app-template
+      sourceRef:
+        kind: HelmRepository
+        name: bjw-s-charts
+        namespace: flux-system
+      version: 5.0.1
+  install:
+    remediation:
+      retries: -1
+  interval: 30m
+  uninstall:
+    keepHistory: false
+  upgrade:
+    cleanupOnFail: true
+    remediation:
+      retries: 3
+  values:
+    controllers:
+      talosctl-oidc:
+        annotations:
+          reloader.stakater.com/auto: 'true'
+        containers:
+          app:
+            command:
+            - /talosctl-oidc
+            - serve
+            env:
+              TALOSCTL_OIDC_CA_CERT: /config/ca.crt
+              TALOSCTL_OIDC_CA_KEY: /config/ca.key
+              TALOSCTL_OIDC_CERT_TTL: 60m
+              TALOSCTL_OIDC_CLIENT_ID: <CLIENT_ID>
+              TALOSCTL_OIDC_DATA_DIR: /data
+              TALOSCTL_OIDC_ENDPOINTS: 192.168.100.31
+              TALOSCTL_OIDC_ISSUER_URL: https://id.techtales.io
+              TALOSCTL_OIDC_LISTEN: :8443
+              TALOSCTL_OIDC_ROLES: os:reader
+            image:
+              repository: ghcr.io/qjoly/talosctl-oidc-server
+              tag: 0.0.4@sha256:ff55155e0f0af646239815bc3e015cb22cfaf05472b0a5e58dc8c22b12a60baa
+            ports:
+            - containerPort: 8443
+              name: https
+            probes:
+              liveness:
+                custom: true
+                enabled: true
+                spec:
+                  httpGet:
+                    path: /healthz
+                    port: 8443
+              readiness:
+                custom: true
+                enabled: true
+                spec:
+                  httpGet:
+                    path: /healthz
+                    port: 8443
+            resources:
+              requests:
+                cpu: 10m
+                memory: 32Mi
+            securityContext:
+              allowPrivilegeEscalation: false
+              capabilities:
+                drop:
+                - ALL
+              readOnlyRootFilesystem: true
+              runAsNonRoot: true
+        pod:
+          securityContext:
+            runAsGroup: 65534
+            runAsNonRoot: true
+            runAsUser: 65534
+        replicas: 1
+        strategy: Recreate
+    defaultPodOptions:
+      securityContext:
+        fsGroup: 65534
+        fsGroupChangePolicy: OnRootMismatch
+    global:
+      createDefaultServiceAccount: false
+    persistence:
+      config:
+        globalMounts:
+        - path: /config
+          readOnly: true
+        name: talosctl-oidc-ca
+        type: secret
+      data:
+        globalMounts:
+        - path: /data
+        type: emptyDir
+    service:
+      app:
+        controller: talosctl-oidc
+        ports:
+          https:
+            port: 8443
+        type: LoadBalancer
+

@sonarqubecloud

Copy link
Copy Markdown

@tyriis-automation

Copy link
Copy Markdown
Contributor

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ EDITORCONFIG editorconfig-checker 10 0 0 0.17s
✅ REPOSITORY gitleaks yes no no 6.35s
✅ YAML prettier 10 0 0 0.6s
✅ YAML yamllint 10 0 0 1.04s

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@tyriis-automation

Copy link
Copy Markdown
Contributor

konflate — summary

Note

+5 added · 0 changed · −0 removed — 5 resources · 3 apps

Image changes

image from to
ghcr.io/qjoly/talosctl-oidc-server sha256:ff55155e0f0a…

View the full rendered diff →

konflate · rendered ae59806 · advisory, not a gate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant