Skip to content

Kubernetes

Contributors: @kdwils, @pushpinderbal

Kubernetes-hosted applications are commonly exposed externally using Ingress Controllers or the newer Gateway API. These can act as a gateway to enforce authentication and authorization policies before traffic reaches your self-hosted applications. This is useful for protecting internal tools, admin interfaces, or services exposed to the internet - without needing to modify the applications themselves, especially those that do not have built-in authentication mechanisms.

Popular reverse proxies like Nginx, Traefik, and Envoy provide Ingress controller and Gateway API implementations for Kubernetes that can be integrated with Tinyauth.

This guide assumes the following prerequisites:

  • An operational Kubernetes cluster
  • An operational Ingress controller or Gateway API implementation (this guide demonstrates ingress-nginx and Istio, but traefik can be used as well).
  • Experience with Kubernetes

Firstly, create a namespace for Tinyauth:

apiVersion: v1
kind: Namespace
metadata:
name: tinyauth

Create the Tinyauth deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: tinyauth
labels:
app: tinyauth
spec:
replicas: 1
selector:
matchLabels:
app: tinyauth
template:
metadata:
labels:
app: tinyauth
spec:
containers:
- name: tinyauth
image: ghcr.io/steveiliop56/tinyauth:v5
ports:
- containerPort: 3000
env:
- name: TINYAUTH_APPURL
value: http://auth.example.com
- name: TINYAUTH_AUTH_USERS
value: user:$$2a$$10$$UdLYoJ5lgPsC0RKqYH/jMua7zIn0g9kPqWmhYayJYLaZQ/FTmH2/u # Username is user and password is password
livenessProbe:
httpGet:
path: /api/healthz
port: 3000
readinessProbe:
httpGet:
path: /api/healthz
port: 3000

Create the service:

apiVersion: v1
kind: Service
metadata:
name: tinyauth
spec:
selector:
app: tinyauth
ports:
- port: 3000
targetPort: 3000
type: ClusterIP

This ingress resource configures ingress-nginx to forward authentication checks for the host my-host.domain.com to a specific URL (auth-url). If the user is not authenticated, they will be redirected to a login page (auth-signin).

Documentation for these annotations can be found in the ingress-nginx repository annotations.md.

  • nginx.ingress.kubernetes.io/auth-url specifies the URL where ingress-nginx should send requests to verify if the user is authenticated.
  • nginx.ingress.kubernetes.io/auth-signin specifies the URL where ingress-nginx should send unauthenticated users to sign in.
  • nginx.ingress.kubernetes.io/auth-signin-redirect-param specifies the key of the query parameter used to set the redirect URI.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://tinyauth.tinyauth.svc.cluster.local:3000/api/auth/nginx"
nginx.ingress.kubernetes.io/auth-signin: "http://auth.example.com/login"
nginx.ingress.kubernetes.io/auth-signin-redirect-param: redirect_uri
spec:
ingressClassName: nginx
rules:
- host: my-host.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 8080

External authorization in Istio is configured using the AuthorizationPolicy CRD and can be set up to use Tinyauth as the external authorization provider for both Ingress and Gateway API resources. Istio uses Envoy proxy under the hood, so this configuration can also be adapted for standalone Envoy filters.

Add Tinyauth as an external authorization provider in your Istio mesh configuration.

extensionProviders:
- name: "tinyauth"
envoyExtAuthzHttp:
service: "tinyauth.tinyauth.svc.cluster.local"
port: "3000"
pathPrefix: "/api/auth/envoy?path="
includeRequestHeadersInCheck: ["cookie", "x-forwarded-for", "x-forwarded-proto", "x-forwarded-host", "accept"]
includeAdditionalHeadersInCheck:
"x-forwarded-proto": "%REQ(:SCHEME)%"
"x-forwarded-host": "%REQ(:AUTHORITY)%"
"x-forwarded-uri": "%REQ(:PATH)%"
"x-forwarded-method": "%REQ(:METHOD)%"
headersToDownstreamOnAllow: ["set-cookie"]
headersToDownstreamOnDeny: ["content-type", "set-cookie"]

If you install Istio using helm, you can supply extensionProviders configuration in the values.yaml files as follows:

meshConfig:
extensionProviders:
- name: "tinyauth"
....<rest of the config as above>....

Given that you have a HTTPRoute under a Gateway that exposes your application, you can now create an AuthorizationPolicy to protect it using Tinyauth.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp-http-route
labels:
app: myapp
spec:
parentRefs:
- name: my-public-gateway
namespace: ingress
sectionName: https
hostnames:
- myapp.example.com
rules:
- backendRefs:
- name: myapp-service
port: 80
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: tinyauth-policy
namespace: ingress
spec:
targetRefs:
- kind: Gateway
group: gateway.networking.k8s.io
name: my-public-gateway
action: CUSTOM
provider:
name: "tinyauth"
rules:
- to:
- operation:
hosts: ["myapp.example.com"]

For more information, refer to the Istio External Authorization and Authorization Policy documentation.