Skip to content

Commit

Permalink
Merge pull request #120 from Kuadrant/tls-oidc-service
Browse files Browse the repository at this point in the history
Serve OIDC (Wristband) HTTP endpoints over TLS
  • Loading branch information
guicassolato authored Jul 5, 2021
2 parents ddd1ff5 + 3bd33ae commit 97f14e0
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 35 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ install: manifests kustomize
uninstall: manifests kustomize
$(KUSTOMIZE) build install | kubectl delete -f -

# Install CertManager to the Kubernetes cluster
.PHONY: cert-manager
cert-manager:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml
kubectl -n cert-manager wait --timeout=300s --for=condition=Available deployments --all

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
deploy: manifests kustomize
cd deploy/base && $(KUSTOMIZE) edit set image authorino=$(AUTHORINO_IMAGE) && $(KUSTOMIZE) edit set namespace $(AUTHORINO_NAMESPACE) && $(KUSTOMIZE) edit set replicas authorino-controller-manager=$(AUTHORINO_REPLICAS)
Expand Down Expand Up @@ -181,12 +187,12 @@ local-push: kind
# Builds the image, pushes to the local cluster and deployes Authorino.
# Sets the imagePullPolicy to 'IfNotPresent' so it doesn't try to pull the image again (just pushed into the server registry)
.PHONY: deploy
local-deploy: docker-build local-push deploy
local-deploy: deploy
kubectl -n $(AUTHORINO_NAMESPACE) patch deployment authorino-controller-manager -p '{"spec": {"template": {"spec":{"containers":[{"name": "manager", "imagePullPolicy":"IfNotPresent"}]}}}}'

# Set up a test/dev local Kubernetes server loaded up with a freshly built Authorino image plus dependencies
.PHONY: local-setup
local-setup: local-cluster-up install namespace local-deploy example-apps
local-setup: docker-build local-cluster-up local-push cert-manager install namespace local-deploy example-apps
kubectl -n $(AUTHORINO_NAMESPACE) wait --timeout=300s --for=condition=Available deployments --all
@{ \
echo "Now you can export the envoy service by doing:"; \
Expand Down
32 changes: 32 additions & 0 deletions deploy/base/certmanager/issuer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# The following manifest contains a self-signed issuer CR
# More document can be found at https://docs.cert-manager.io
# WARNING: Targets CertManager 1.4.0 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ca-cert
namespace: system
spec:
commonName: "*.$(AUTHORINO_NAMESPACE).svc"
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: authorino-ca-cert # this secret will not be prefixed, since it's not managed by kustomize
isCA: true
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
namespace: system
spec:
ca:
secretName: authorino-ca-cert
4 changes: 3 additions & 1 deletion deploy/base/certmanager/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
resources:
- certificate.yaml
- issuer.yaml
- oidc-server-cert.yaml
# - webhook-server-cert.yaml

configurations:
- kustomizeconfig.yaml
16 changes: 16 additions & 0 deletions deploy/base/certmanager/oidc-server-cert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# The following manifest contains a certificate CR for Authorino OIDC server (OpenID Connect config and JWKS for the Festival Wristbands)
# More document can be found at https://docs.cert-manager.io
# WARNING: Targets CertManager 1.4.0 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: oidc-server-cert
namespace: system
spec:
dnsNames:
- $(OIDC_SERVICE_NAME).$(AUTHORINO_NAMESPACE).svc
- $(OIDC_SERVICE_NAME).$(AUTHORINO_NAMESPACE).svc.cluster.local
issuerRef:
kind: Issuer
name: ca-issuer
secretName: authorino-oidc-server-cert # this secret will not be prefixed, since it's not managed by kustomize
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
# The following manifests contain a self-signed issuer CR and a certificate CR.
# The following manifest contains a certificate CR for the webhook server
# More document can be found at https://docs.cert-manager.io
# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for
# breaking changes
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1alpha2
# WARNING: Targets CertManager 1.4.0 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
Expand Down
21 changes: 19 additions & 2 deletions deploy/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ kind: Kustomization

resources:
- manager.yaml
- wristband_service.yaml
- oidc_service.yaml
- leader_election_role.yaml
- leader_election_role_binding.yaml
- auth_proxy_service.yaml
- certmanager
#- webhook
#- certmanager
#- prometheus
#- scorecard

Expand All @@ -26,6 +26,7 @@ commonLabels:

patchesStrategicMerge:
- patches/manager_auth_proxy_patch.yaml
- patches/oidc_server_cert_patch.yaml
#- patches/manager_webhook_patch.yaml
#- patches/webhookcainjection_patch.yaml

Expand All @@ -37,3 +38,19 @@ images:
replicas:
- count: 1
name: authorino-controller-manager

vars:
- fieldref:
fieldPath: metadata.namespace
name: AUTHORINO_NAMESPACE
objref:
apiVersion: v1
kind: Service
name: authorization
- fieldref:
fieldPath: metadata.name
name: OIDC_SERVICE_NAME
objref:
apiVersion: v1
kind: Service
name: oidc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: wristband
name: oidc
labels:
app: authorino
spec:
selector:
app: authorino
control-plane: controller-manager
ports:
- name: oidc
port: 8003
- name: https
port: 8083
protocol: TCP
24 changes: 24 additions & 0 deletions deploy/base/patches/oidc_server_cert_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
volumeMounts:
- name: oidc-cert
mountPath: /etc/ssl/certs/tls.crt
subPath: tls.crt
readOnly: true
- name: oidc-cert
mountPath: /etc/ssl/private/tls.key
subPath: tls.key
readOnly: true
volumes:
- name: oidc-cert
secret:
defaultMode: 420
secretName: authorino-oidc-server-cert
10 changes: 5 additions & 5 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ spec:

# Festival Wristband (only if you want JWTs issued by Authorino at the end of the auth pipeline)
wristband:
issuer: http://authorino.svc.cluster.local:8003/namespace/my-api-protection
issuer: https://authorino-oidc.authorino.svc.cluster.local:8083/namespace/my-api-protection
customClaims:
- name: foo
value: bar
Expand Down Expand Up @@ -314,7 +314,7 @@ spec:
in: authorization_header
keySelector: APIKEY
wristband:
issuer: http://authorino.svc.cluster.local:8003/my-namespace/talker-api-protection
issuer: https://authorino-oidc.authorino.svc:8083/my-namespace/talker-api-protection
customClaims:
- name: aud
value: internal
Expand All @@ -331,8 +331,8 @@ spec:

The signing key names listed in `signingKeyRefs` must match the names of Kubernetes `Secret` resources created in the same namespace, where each secret contains a `key.pem` entry that holds the value of the private key that will be used to sign the wristbands issued, formatted as [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). The first key in this list will be used to sign the wristbands, while the others are kept to support key rotation.

For each protected API configured for the Festival Wristband issuing, Authorino exposes the following OpenID Connect Discovery well-known endpoints:
For each protected API configured for the Festival Wristband issuing, Authorino exposes the following OpenID Connect Discovery well-known endpoints (available for requests within the cluster):
- **OpenID Connect configuration:**<br/>
http://authorino.svc.cluster.local:8003/{namespace}/{api-protection-name}/.well-known/openid-configuration
https://authorino-oidc.authorino.svc:8083/{namespace}/{api-protection-name}/.well-known/openid-configuration
- **JSON Web Key Set (JWKS) well-known endpoint:**<br/>
http://authorino.svc.cluster.local:8003/{namespace}/{api-protection-name}/.well-known/openid-connect/certs
https://authorino-oidc.authorino.svc:8083/{namespace}/{api-protection-name}/.well-known/openid-connect/certs
8 changes: 4 additions & 4 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,19 +566,19 @@ The payload of the wristband (decoded) shall look like the following:
"born": "2021-05-13T15:42:41Z", # custom claim (dynamic value)
"exp": 1620921395,
"iat": 1620921095,
"iss": "http://authorino-authorization:8003/authorino/talker-api-protection",
"iss": "https://authorino-oidc.authorino.svc:8083/authorino/talker-api-protection",
"sub": "84d3f3a06f5569e06a050516363f0a65c1789d3433bb4fed5d48801997d5c30e" # SHA256 of the resolved identity in the initial request (based on API key auth)
}
```

To discover the OpenID Connect configuration and JSON Web Key Set (JWKS) to verify and validate wristbands issued on requests to this protected API:

```
kubectl -n authorino port-forward service/authorino-authorization 8003:8003
kubectl -n authorino port-forward service/authorino-oidc 8083:8083
```

OpenID Connect configuration well-known endpoint:<br/>
http://localhost:8003/authorino/talker-api-protection/.well-known/openid-configuration
http://localhost:8083/authorino/talker-api-protection/.well-known/openid-configuration

JSON Web Key Set (JWKS) well-known endpoint:<br/>
http://localhost:8003/authorino/talker-api-protection/.well-known/openid-connect/certs
http://localhost:8083/authorino/talker-api-protection/.well-known/openid-connect/certs
4 changes: 2 additions & 2 deletions examples/wristband.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ spec:
keySelector: APIKEY
- name: wristband
oidc:
endpoint: http://authorino-wristband:8003/authorino/talker-api-protection
endpoint: https://authorino-oidc.authorino.svc:8083/authorino/talker-api-protection
wristband:
issuer: http://authorino-wristband:8003/authorino/talker-api-protection
issuer: https://authorino-oidc.authorino.svc:8083/authorino/talker-api-protection
customClaims:
- name: aud
value: internal
Expand Down
7 changes: 3 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ var (
watchNamespace = common.FetchEnv("WATCH_NAMESPACE", "")
authorinoWatchedSecretLabel = common.FetchEnv("AUTHORINO_SECRET_LABEL_KEY", defaultAuthorinoWatchedSecretLabel)
extAuthGRPCPort = common.FetchEnv("EXT_AUTH_GRPC_PORT", "50051")
oidcHTTPPort = common.FetchEnv("OIDC_HTTP_PORT", "8003")
oidcHTTPPort = common.FetchEnv("OIDC_HTTP_PORT", "8083")
oidcCAPath = common.FetchEnv("OIDC_CA_PATH", "/etc/ssl")
)

func init() {
Expand Down Expand Up @@ -206,12 +207,10 @@ func startOIDCServer(serviceCache cache.Cache) {
logger.Info("starting oidc service", "port", oidcHTTPPort)

go func() {
if err := http.Serve(lis, nil); err != nil {
if err := http.ServeTLS(lis, nil, oidcCAPath+"/certs/tls.crt", oidcCAPath+"/private/tls.key"); err != nil {
logger.Error(err, "failed to start oidc service")
os.Exit(1)
}

// TODO: ServeTLS
}()
}
}

0 comments on commit 97f14e0

Please sign in to comment.