Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/auth-broker/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: auth-broker
description: Token broker service that validates pod identity via Kubernetes TokenReview and serves OIDC access tokens
type: application
version: 0.1.2
version: 0.1.3
appVersion: 0.1.0

dependencies:
Expand Down
3 changes: 3 additions & 0 deletions charts/auth-broker/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ spec:
- name: config
mountPath: /etc/auth-broker
readOnly: true
env:
- name: LOG_LEVEL
value: "info"
volumes:
- name: config
secret:
Expand Down
2 changes: 1 addition & 1 deletion charts/auth-broker/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ image:
registry: ""
repository: ghcr.io/diamondlightsource/workflows-auth-broker
tag: latest
digest: ""
digest: "sha256:70cc33ff46ed8de53ebb02b569260a5b63add937d12021eff96292ce977fb2ea"
pullPolicy: IfNotPresent


Expand Down
2 changes: 1 addition & 1 deletion charts/workflows/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: workflows
description: Data Analysis workflow orchestration
type: application
version: 0.13.55
version: 0.13.56
dependencies:
- name: argo-workflows
repository: https://argoproj.github.io/argo-helm
Expand Down
6 changes: 5 additions & 1 deletion charts/workflows/staging-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ postgresql-ha:
allowTriggerUid: true

authenticatedWorkflows:
enabled: true
authDaemon:
enabled: false
envoy:
enabled: false
graphAddress: staging.workflows.diamond.ac.uk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if .Values.authenticatedWorkflows.enabled }}
{{- if .Values.authenticatedWorkflows.authDaemon.enabled }}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
Expand Down
364 changes: 364 additions & 0 deletions charts/workflows/templates/inject-envoy-sidecar-clusterpolicy.yaml

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions charts/workflows/test-policy/inject-envoy-sidecar/chainsaw-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: envoy-authz-service-account-token
spec:
namespace: envoy-authz-chainsaw
timeouts:
cleanup: 90s
delete: 30s
assert: 300s
concurrent: false
steps:
- name: test envoy policy works
try:
- apply:
file: fake-graph.yaml

- assert:
file: fake-graph.yaml

- apply:
file: fake-auth-broker.yaml

- assert:
file: fake-auth-broker.yaml

- script:
content: |
set -eu
pwd
: "${CHART_DIR:=../../}"

helm template chainsaw-envoy-auth "$CHART_DIR" \
--namespace "$NAMESPACE" \
--values values-chainsaw.yaml \
| yq 'select(.kind == "ClusterPolicy" and .metadata.name == "chainsaw-envoy-auth-inject-envoy-sidecar")' | kubectl apply -f -

kubectl wait \
--for=condition=Ready \
clusterpolicy/chainsaw-envoy-auth-inject-envoy-sidecar \
--timeout=60s

- apply:
file: pod.yaml

- assert:
file: pod-mutated.yaml

- assert:
file: pod-succeeded.yaml

- script:
content: |
set -eu

echo "Checking fake-auth-broker logs"

LOGS="$(kubectl logs \
--namespace "$NAMESPACE" \
-l app=fake-auth-broker \
-c fake-auth-broker)"

echo "$LOGS" | grep -Fq 'TOKEN_PRESENT true'

- script:
content: |
set -eu

echo "Checking fake-graph logs"

LOGS="$(kubectl logs \
--namespace "$NAMESPACE" \
-l app=fake-graph \
-c fake-graph)"

echo "$LOGS" | grep -Fq 'TOKEN_HAS_AUTH_HEADER true' || {
echo "Expected TOKEN_HAS_AUTH_HEADER true in fake-graph logs"
echo "$LOGS"
exit 1
}

echo "$LOGS" | grep -Fq 'TOKEN_LEAKED false' || {
echo "Expected TOKEN_PRESENT false in fake-graph logs"
echo "$LOGS"
exit 1
}

catch:
- describe:
apiVersion: v1
kind: Pod
name: envoy-auth-test

- podLogs:
name: envoy-auth-test
container: workflows-auth-envoy

- podLogs:
name: envoy-auth-test
container: main

- podLogs:
selector: app=fake-auth-broker
container: fake-auth-broker

- podLogs:
selector: app=fake-graph
container: fake-graph

finally:
- script:
content: |
kubectl delete clusterpolicy chainsaw-envoy-auth-inject-envoy-sidecar --ignore-not-found
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: fake-auth-broker
data:
server.py: |
from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
def do_POST(self):
token = self.headers.get("k8s-pod-service-account-token")
token_present = bool(token)
print(f"TOKEN_PRESENT {str(token_present).lower()}", flush=True)

if token_present:
self.send_response(200)
self.send_header("authorization", "Bearer fake-auth-broker-token")
self.end_headers()
self.wfile.write(b"ok")
else:
self.send_response(403)
self.end_headers()
self.wfile.write(b"missing or invalid token")

HTTPServer(("0.0.0.0", 8080), Handler).serve_forever()
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fake-auth-broker
spec:
replicas: 1
selector:
matchLabels:
app: fake-auth-broker
template:
metadata:
labels:
app: fake-auth-broker
spec:
terminationGracePeriodSeconds: 1
containers:
- name: fake-auth-broker
image: python:3.14-alpine
command:
- python
- /app/server.py
ports:
- containerPort: 8080
volumeMounts:
- name: app
mountPath: /app
volumes:
- name: app
configMap:
name: fake-auth-broker
---
apiVersion: v1
kind: Service
metadata:
name: fake-auth-broker
spec:
selector:
app: fake-auth-broker
ports:
- name: http
port: 8080
targetPort: 8080
72 changes: 72 additions & 0 deletions charts/workflows/test-policy/inject-envoy-sidecar/fake-graph.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: fake-graph
data:
server.py: |
from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
def do_POST(self):
has_expected_auth_header = self.headers.get("authorization") == "Bearer fake-auth-broker-token"
print(f"TOKEN_HAS_AUTH_HEADER {str(has_expected_auth_header).lower()}", flush=True)
leaked = self.headers.get("k8s-pod-service-account-token") is not None
print(f"TOKEN_LEAKED {str(leaked).lower()}", flush=True)

if has_expected_auth_header and not leaked:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curiosity. Why are we placing the scripts as is into the yaml and not having a /scripts folder?

body = b'{"data":{"workflowTemplates":{"nodes":[{"name":"mock-template"}]}}}'
self.send_response(200)
self.send_header("content-type", "application/json")
self.send_header("content-length", str(len(body)))
self.end_headers()
self.wfile.write(body)
else:
self.send_response(500)
self.end_headers()
self.wfile.write(b"invalid token or headers")
return

HTTPServer(("0.0.0.0", 8080), Handler).serve_forever()
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fake-graph
spec:
replicas: 1
selector:
matchLabels:
app: fake-graph
template:
metadata:
labels:
app: fake-graph
spec:
terminationGracePeriodSeconds: 1
containers:
- name: fake-graph
image: python:3.14-alpine
command:
- python
- /app/server.py
ports:
- containerPort: 8080
volumeMounts:
- name: app
mountPath: /app
volumes:
- name: app
configMap:
name: fake-graph
---
apiVersion: v1
kind: Service
metadata:
name: fake-graph
spec:
selector:
app: fake-graph
ports:
- name: http
port: 8080
targetPort: 8080
22 changes: 22 additions & 0 deletions charts/workflows/test-policy/inject-envoy-sidecar/pod-mutated.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: v1
kind: Pod
metadata:
name: envoy-auth-test
labels:
workflows.argoproj.io/workflow: envoy-auth-test
annotations:
workflows.diamond.ac.uk/authenticated: "true"

spec:
initContainers:
- name: "workflows-auth-init"
- name: "workflows-auth-envoy-validate"
- name: "workflows-auth-envoy"

containers:
- name: main
env:
- name: GRAPH_URL
value: "http://127.0.0.1:6000/graphql"
- name: GRAPH_URL_WS
value: "http://127.0.0.1:6000/graphql/ws"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Pod
metadata:
name: envoy-auth-test
status:
phase: Succeeded
37 changes: 37 additions & 0 deletions charts/workflows/test-policy/inject-envoy-sidecar/pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: envoy-auth-test
labels:
workflows.argoproj.io/workflow: envoy-auth-test
annotations:
workflows.diamond.ac.uk/authenticated: "true"
spec:
restartPolicy: Never
terminationGracePeriodSeconds: 1

containers:
- name: main
image: curlimages/curl:8.12.1
command:
- sh
- -c
args:
- |
set -eu

echo "GRAPH_URL=${GRAPH_URL}"

RESPONSE="$(curl -v \
--fail \
--silent \
--show-error \
--connect-timeout 5 \
-X POST \
"${GRAPH_URL}" \
-H 'Content-Type: application/json' \
--data '{"query":"query WorkflowTemplates { workflowTemplates { nodes { name } } }"}')"

echo "${RESPONSE}"

echo "${RESPONSE}" | grep -q '"workflowTemplates"'
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
authenticatedWorkflows:
authDaemon:
enabled: false
envoy:
enabled: true
authBrokerServerUri: http://fake-auth-broker.envoy-authz-chainsaw.svc.cluster.local:8080
authBrokerServerSocketAddress: fake-auth-broker.envoy-authz-chainsaw.svc.cluster.local
authBrokerServerSocketPort: 8080
graphAddress: fake-graph.envoy-authz-chainsaw.svc.cluster.local
graphPort: 8080
tls:
enabled: false
logLevel: warn
Loading
Loading