Skip to content

Commit

Permalink
Added athenz-oauth2
Browse files Browse the repository at this point in the history
  • Loading branch information
ctyano committed Jun 7, 2024
1 parent f1d2480 commit 0691541
Show file tree
Hide file tree
Showing 14 changed files with 995 additions and 0 deletions.
8 changes: 8 additions & 0 deletions kubernetes/athenz-oauth2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.pem
*.jks
*.pkcs12
*.srl
*.jar
.ntoken
athenz.conf
admin
162 changes: 162 additions & 0 deletions kubernetes/athenz-oauth2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
ifeq ($(DOCKER_REGISTRY),)
DOCKER_REGISTRY=ghcr.io/ctyano/
endif

clean-athenz-oauth2:
kubectl delete -k kustomize

register-athenz-oauth2:
kubectl -n athenz exec deployment/athenz-cli -it -- \
curl \
-sv \
-d"{\"name\":\"$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g')\",\"adminUsers\":[\"user.athenz_admin\"]}" \
-H"Content-Type: application/json" \
--key /var/run/athenz/athenz_admin.private.pem \
--cert /var/run/athenz/athenz_admin.cert.pem \
"https://athenz-zms-server.athenz:4443/zms/v1/domain"
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d \
sys.auth \
set-domain-template \
instance_provider \
provider="$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)/\1/g')" \
dnssuffix="$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^DNS_SUFFIX | sed -e 's/DNS_SUFFIX=\(.*\)/\1/g')"
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d \
$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
add-service \
$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^SERVICEACCOUNT | sed -e 's/SERVICEACCOUNT=\(.*\)/\1/g') \
0 \
$$(cat kustomize/keys/oauth2.public.pem | base64 | tr -d '\r\n' | tr '\+\=\/' '\.\-\_') ||:
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d \
$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
set-domain-template \
identity_provisioning \
instanceprovider="sys.auth.zts" \
service="$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^SERVICEACCOUNT | sed -e 's/SERVICEACCOUNT=\(.*\)/\1/g')"
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d \
$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
set-domain-template \
identity_provisioning \
instanceprovider="$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)/\1/g')" \
service="$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^SERVICEACCOUNT | sed -e 's/SERVICEACCOUNT=\(.*\)/\1/g')"
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d $$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
add-group-role \
envoyclients ||:
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d $$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
add-policy \
envoyclients \
grant get to envoyclients on /extauthz* ||:
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d $$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
show-domain

check-register-athenz-oauth2:
SLEEP_SECONDS=5; \
WAITING_THRESHOLD=60; \
i=0; \
while true; do \
printf "\n***** Waiting for athenz($$(( $$i * $${SLEEP_SECONDS} ))s/$${WAITING_THRESHOLD}s) *****\n"; \
kubectl -n athenz exec deployment/athenz-cli -it -- \
curl \
-sf \
-H"Content-type: application/json" \
-H"X-Auth-Request-Preferred-Username: user.athenz_admin" \
"https://athenz-zts-server.athenz:4443/zts/v1/domain/$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g')/service/$$(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^SERVICEACCOUNT | sed -e 's/SERVICEACCOUNT=\(.*\)/\1/g')" \
&& break \
|| echo "Waiting for ZTS to sync with ZMS..."; \
sleep $${SLEEP_SECONDS}; \
i=$$(( i + 1 )); \
if [ $$i -eq $$(( $${WAITING_THRESHOLD} / $${SLEEP_SECONDS} )) ]; then \
printf "\n\n** Waiting ($$(( $$i * $${SLEEP_SECONDS} ))s) reached to threshold($${WAITING_THRESHOLD}s) **\n\n"; \
kubectl -n athenz get all | grep -E "pod/.*0/1" | sed -e 's/^\(pod\/[^ ]*\) *0\/1.*/\1/g' | xargs -I%% kubectl -n athenz logs %% --all-containers=true ||:; \
kubectl -n athenz get all | grep -E "pod/.*0/1" | sed -e 's/^\(pod\/[^ ]*\) *0\/1.*/\1/g' | xargs -I%% kubectl -n athenz describe %% ||:; \
kubectl -n athenz get all; \
exit 1; \
fi; \
done
kubectl -n athenz get all
@echo ""
@echo "**************************************"
@echo "** Athenz Authorizer is functioning *"
@echo "**************************************"
@echo ""

kustomize-edit-athenz-oauth2-image:
if [ "$(DOCKER_REGISTRY)" != "ghcr.io/ctyano/" ]; then \
( \
cd kustomize \
&& kustomize edit set image ghcr.io/ctyano/athenz-cli:latest=$(DOCKER_REGISTRY)athenz-cli:latest \
&& kustomize edit set image ghcr.io/ctyano/k8s-athenz-sia:latest=$(DOCKER_REGISTRY)k8s-athenz-sia:latest \
) \
fi

deploy-athenz-oauth2: kustomize-edit-athenz-oauth2-image
kubectl apply -k kustomize

test-athenz-oauth2:
SLEEP_SECONDS=5; \
WAITING_THRESHOLD=60; \
i=0; \
while true; do \
printf "\n***** Waiting for athenz($$(( $$i * $${SLEEP_SECONDS} ))s/$${WAITING_THRESHOLD}s) *****\n"; \
( \
test $$(( $$(kubectl -n athenz get all | grep oauth2 | grep -E "0/1" | wc -l) )) -eq 0 \
&& \
kubectl -n athenz exec deployment/oauth2-deployment -it -c sia -- \
ls \
-alF \
/var/run/athenz/tls.key \
/var/run/athenz/tls.crt \
/var/run/athenz/ca.crt \
) \
&& break \
|| echo "Waiting for Identity Provisioning..."; \
sleep $${SLEEP_SECONDS}; \
i=$$(( i + 1 )); \
if [ $$i -eq $$(( $${WAITING_THRESHOLD} / $${SLEEP_SECONDS} )) ]; then \
printf "\n\n** Waiting ($$(( $$i * $${SLEEP_SECONDS} ))s) reached to threshold($${WAITING_THRESHOLD}s) **\n\n"; \
kubectl -n athenz get all | grep -E "pod/oauth2-" | sed -e 's/^\(pod\/[^ ]*\) *[0-9]\/[0-9].*/\1/g' | xargs -I%% kubectl -n athenz logs %% --all-containers=true ||:; \
kubectl -n athenz get all | grep -E "pod/oauth2-" | sed -e 's/^\(pod\/[^ ]*\) *[0-9]\/[0-9].*/\1/g' | xargs -I%% kubectl -n athenz describe %% ||:; \
kubectl -n athenz get all; \
exit 1; \
fi; \
done
kubectl -n athenz get all
@echo ""
@echo "**************************************"
@echo "* Authorizer provisioning successful *"
@echo "**************************************"
@echo ""
39 changes: 39 additions & 0 deletions kubernetes/athenz-oauth2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# athenz-oauth2

## Configuration

Files below must be configured for each use cases accordingly

1. [athenz-oauth2.env](kustomize/athenz-oauth2/athenz-oauth2.env)
1. [athenz-sia.env](kustomize/athenz-sia/athenz-sia.env)
1. [config.yaml](kustomize/athenz-oauth2/policy/config.yaml)

## Deployment

```
kubectl -n athenz apply -k kustomize
```

## Registering Authorizer Service to Athenz

```
make register-athenz-oauth2
```

confirm registration with:

```
kubectl -n athenz exec deployment/athenz-cli -it -- \
zms-cli \
-z https://athenz-zms-server.athenz:4443/zms/v1 \
-key /var/run/athenz/athenz_admin.private.pem \
-cert /var/run/athenz/athenz_admin.cert.pem \
-d $(cat kustomize/athenz-sia/athenz-sia.env | grep -E ^PROVIDER_SERVICE | sed -e 's/PROVIDER_SERVICE=\(.*\)\.\(.*\)/\1/g') \
show-domain
```

## Debugging

```
kubectl -n athenz exec -it deployment/oauth2-deployment -c athenz-cli -- /bin/sh -c "curl -sv --resolve oauth2.athenz.svc.cluster.local:443:127.0.0.1 https://oauth2.athenz.svc.cluster.local/echoserver | jq -r .request"
```
1 change: 1 addition & 0 deletions kubernetes/athenz-oauth2/kustomize/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
secret.yaml
175 changes: 175 additions & 0 deletions kubernetes/athenz-oauth2/kustomize/athenz-sia/athenz-sia.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#
# Booting mode of SIA
# must be one of "init" or "refresh"
# "init": SIA will exit after a single credential retrieval
# "refresh": SIA will run as a continuous process to retrieve credentials periodically and also runs as an HTTP server to provide credentials and metrics
#
MODE=init
#
# Athenz ZTS URL for SIA to request for X.509 certificate
# https://<ZTS HOST>:<ZTS PORT>/zts/v1
#
ENDPOINT=https://athenz-zts-server.athenz:4443/zts/v1
#
# Athenz Service name for the cloud provider
# <Athenz Domain>.<Athenz Service> (e.g. "cloud-provider-top-level-domain.cluster-name.oauth2-service")
#
PROVIDER_SERVICE=athenz.identityprovider
#
# Suffix restriction for SANs(Subject Alternative Names) DNS field in X.509 certificate
# Subject Alternative Names:
# "DNS: <any name>.<Provider DNS Suffix>"
# "DNS: <Instance ID>.instanceid.athenz.<Provider DNS Suffix>"
# Note: <Provider DNS Suffix> must meat the suffix registered in Athenz (e.g. ".athenz.cloud")
#
DNS_SUFFIX=svc.cluster.local
#
# Refresh interval for SIA to request to ZTS periodically in containers to get X.509 identity certificate
# Note: This only applies for refresh mode
#
REFRESH_INTERVAL=30s
#
# Delay interval for SIA to boot
# This may be useful when you want to prevent large number of SIA to make requests to ZTS concurrently in a short period
#
DELAY_JITTER_SECONDS=0
#
# File paths to store Athenz X.509 certificate key file
#
KEY_FILE=/var/run/athenz/tls.key
#
# File paths to store Athenz X.509 certificate file
#
CERT_FILE=/var/run/athenz/tls.crt
#
# File paths to store Athenz X.509 ca certificate file that can verify CERT_FILE
#
CA_CERT_FILE=/var/run/athenz/ca.crt
#
# Directory to store the log files
#
LOG_DIR=/dev/null
#
# Log level to print logs
# Available values are: TRACE, DEBUG, INFO, WARNING, ERROR, FATAL or PANIC
#
LOG_LEVEL=DEBUG
#
# Set "read" or "read+write" for storing backup of X.509 certificate to Kubernetes Secret
# Set "write" or "read+write" for reading backup of X.509 certificate from Kubernetes Secret
# Set "" for disabling Kubernetes Secret backup
# "write" or "read+write" must be run uniquely for each secret to prevent conflict
#
BACKUP=""
#
# Kubernetes TLS Secret to backup and load X.509 certificate files
#
CERT_SECRET=oauth2-tls
#
# Cloud users Athenz Domain to map to SIA
#
# if <ATHENZ_DOMAIN> is not "", Athenz Domain would be:
# "<ATHENZ_PREFIX><ATHENZ_DOMAIN><ATHENZ_SUFFIX>"
# <ATHENZ_PREFIX> must end with "."
# <ATHENZ_SUFFIX> must start with "."
# Example:
# ATHENZ_PREFIX="some-tld.foo."
# ATHENZ_DOMAIN="cluster-bar"
# ATHENZ_SUFFIX=".baz"
#
# if <ATHENZ_DOMAIN> is "", Athenz Domain would be:
# "<ATHENZ_PREFIX><NAMESPACE><ATHENZ_SUFFIX>"
# <NAMESPACE> is Kubernetes Namespace set by default
# <ATHENZ_PREFIX> must end with "."
# <ATHENZ_SUFFIX> must start with "."
# Example:
# ATHENZ_PREFIX="some-tld.foo."
# NAMESPACE="namespace-bar"
# ATHENZ_SUFFIX=".baz"
#
# NAMESPACE may be extracted from metadata.namespace in Kubernetes manifests
#
NAMESPACE=
ATHENZ_DOMAIN=
ATHENZ_PREFIX=
ATHENZ_SUFFIX=
#
# Kubernetes Service Account as same name as Athenz Service
#
# SERVICEACCOUNT may be extracted from spec.serviceAccountName in Kubernetes Pod manifests
#
SERVICEACCOUNT=oauth2
#
# File path for Kubernetes Service Account Token
#
SA_TOKEN_FILE=/var/run/secrets/kubernetes.io/bound-serviceaccount/token
#
# Kubernetes Pod IP
#
# POD_IP may be extracted from status.podIP in Kubernetes manifests
#
POD_IP=
#
# Kubernetes Pod UID
#
# POD_UID may be extracted from metadata.uid in Kubernetes manifests
#
POD_UID=
#
# CA certificate to verify ZTS server certificate
#
SERVER_CA_CERT=/etc/ssl/certs/ca-certificates.crt
#
# Comma separated Athenz Roles to retrieve role certificates (if empty, role certificate retrieval will be skipped)
# <Domain>:role.<Role>,<Domain>:role.<Role>...
#
TARGET_DOMAIN_ROLES=
#
# Directory path to store Athenz X.509 role certificate files
#
ROLECERT_DIR=
#
# Directory path to store Athenz role token files
#
TOKEN_DIR=
#
# Token type for Athenz role tokens
#
TOKEN_TYPE=roletoken+accesstoken
#
# Refresh interval for SIA to request to ZTS periodically in containers to get role tokens
#
TOKEN_REFRESH_INTERVAL=30s
#
# Server address to listen as token provider sidecar (e.g. :8180)
#
TOKEN_SERVER_ADDR=:8180
#
# Server address to listen as metrics exporter sidecar (e.g. :9999)
#
METRICS_SERVER_ADDR=:9999
#
# Delete Instance ID at container shutdown
#
DELETE_INSTANCE_ID=true
#
# Comma separated Athenz Domains to retrieve policies (if empty, Athenz Policy retrieval will be skipped)
# <TopLevelDomain.SubDomain>,<TopLevelDomain.SubDomain>...
#
AUTHORIZATION_POLICY_DOMAINS=athenz
#
# Server address to listen as authorization sidecar (e.g. :8280)
#
AUTHORIZATION_SERVER_ADDR=:8280
#
# Refresh interval for SIA to request to ZTS periodically in containers to get policies
#
POLICY_REFRESH_INTERVAL=30s
#
# Refresh interval for SIA to request to ZTS periodically in containers to get public keys
#
PUBLICKEY_REFRESH_INTERVAL=30s
#
# Cache interval for SIA to authorize requests without comparing with roles and policies
#
AUTHORIZATION_CACHE_INTERVAL=30s
Loading

0 comments on commit 0691541

Please sign in to comment.