Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support APIKey authentication #5580

Merged
merged 44 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ba8f0c2
always load njs module
haywoodsh May 9, 2024
d046e57
accept api key policy yaml
haywoodsh May 20, 2024
94851fc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2024
20f7d06
add njs and nginx config
May 20, 2024
fd33e3b
move js import to http
May 22, 2024
5ce5ac5
update schema and allow update after NIC starts
haywoodsh May 24, 2024
4d2ee9d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 24, 2024
c529d8a
remove hardcoded variable
May 24, 2024
7a579a9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 24, 2024
30c019d
add updated njs
May 28, 2024
2643320
move js set outside location
May 28, 2024
c4b0bdf
use nginx.org/apikey secret type
haywoodsh May 29, 2024
be1b05e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 29, 2024
2a7f66a
simplify njs
May 31, 2024
083df06
make query params work
May 31, 2024
512e27b
clean up template files
May 31, 2024
573be80
add api key secret validation to reject duplicated keys, remove repea…
haywoodsh Jun 6, 2024
5a8916b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 6, 2024
8f877e3
fix linting, remove unused structs, update crds and codegen
haywoodsh Jun 6, 2024
1d91b7c
add unit tests, unique map names, add validate apikey location block …
haywoodsh Jun 11, 2024
3e53c4b
add python tests for vs and vsr
Jun 12, 2024
160a3b4
Merge branch 'main' into feat/api-key
Jun 12, 2024
b49634f
Merge branch 'main' into feat/api-key
Jun 12, 2024
028ff04
fix dockerfile merge
Jun 12, 2024
93a1e0b
add wait until pods are ready
Jun 12, 2024
3ac68d4
update error message
haywoodsh Jun 12, 2024
8c1d9d1
test setting same namespace
Jun 12, 2024
b4d382f
Merge remote-tracking branch 'refs/remotes/origin/feat/api-key' into …
Jun 12, 2024
9682420
custom objects
Jun 12, 2024
48f8054
add crd print
Jun 13, 2024
99ba140
add unit tests
haywoodsh Jun 13, 2024
1f50525
Add example readme for apikey auth policy
Jun 13, 2024
cf4fb2c
Merge branch 'main' into feat/api-key
Jun 13, 2024
e9a0a75
clean up
Jun 13, 2024
21be26e
Merge remote-tracking branch 'refs/remotes/origin/feat/api-key' into …
Jun 13, 2024
9806d6b
further cleanup
Jun 13, 2024
8956744
clean up test
Jun 13, 2024
fff5d6d
add unit tests, clean up code
haywoodsh Jun 13, 2024
b983616
remove logs, refactor, add tests
haywoodsh Jun 14, 2024
ec753ce
remove logs
haywoodsh Jun 14, 2024
ec84a05
Merge branch 'main' into feat/api-key
Jun 14, 2024
c6bd588
add api key auth to telemetry
Jun 14, 2024
d415866
Merge branch 'main' into feat/api-key
Jun 14, 2024
fec5a3b
Merge branch 'main' into feat/api-key
Jun 17, 2024
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
1 change: 1 addition & 0 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ RUN --mount=type=bind,target=/tmp mkdir -p /var/lib/nginx /etc/nginx/secrets /et
&& [ -z "${BUILD_OS##*plus*}" ] && PLUS=-plus; cp -a /tmp/internal/configs/version1/nginx$PLUS.ingress.tmpl /tmp/internal/configs/version1/nginx$PLUS.tmpl \
/tmp/internal/configs/version2/nginx$PLUS.virtualserver.tmpl /tmp/internal/configs/version2/nginx$PLUS.transportserver.tmpl / \
&& if [ -z "${BUILD_OS##*plus*}" ]; then mkdir -p /etc/nginx/state_files/; fi \
&& mkdir -p /etc/nginx/njs/ && cp -a /tmp/internal/configs/njs/* /etc/nginx/njs/ \
&& chown -R 101:0 /etc/nginx /var/cache/nginx /var/lib/nginx /var/log/nginx /*.tmpl \
&& chmod -R g=u /etc/nginx /var/cache/nginx /var/lib/nginx /var/log/nginx /*.tmpl \
&& rm -f /etc/nginx/conf.d/*
Expand Down
23 changes: 23 additions & 0 deletions config/crd/bases/k8s.nginx.org_policies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@ spec:
type: string
type: array
type: object
apiKey:
properties:
clientSecret:
type: string
rejectCodes:
properties:
noMatch:
type: integer
notSupplied:
type: integer
type: object
suppliedIn:
properties:
header:
items:
type: string
type: array
query:
items:
type: string
type: array
type: object
type: object
basicAuth:
description: |-
BasicAuth holds HTTP Basic authentication configuration
Expand Down
23 changes: 23 additions & 0 deletions deploy/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,29 @@ spec:
type: string
type: array
type: object
apiKey:
properties:
clientSecret:
type: string
rejectCodes:
properties:
noMatch:
type: integer
notSupplied:
type: integer
type: object
suppliedIn:
properties:
header:
items:
type: string
type: array
query:
items:
type: string
type: array
type: object
type: object
basicAuth:
description: |-
BasicAuth holds HTTP Basic authentication configuration
Expand Down
15 changes: 15 additions & 0 deletions examples/custom-resources/api-key/api-key-policy-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
name: api-key-policy-2
spec:
apiKey:
suppliedIn:
header:
- "X-header-name"
query:
- "queryName"
rejectCodes: # optional
notSupplied: 408
noMatch: 410
clientSecret: api-key-client-secret-2
17 changes: 17 additions & 0 deletions examples/custom-resources/api-key/api-key-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
name: api-key-policy
spec:
apiKey:
suppliedIn:
header:
- "X-header-name"
- "apikey"
- "some-other-header"
query:
- "queryName"
rejectCodes: # optional
notSupplied: 401
noMatch: 403
clientSecret: api-key-client-secret-1
8 changes: 8 additions & 0 deletions examples/custom-resources/api-key/api-key-secret-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: api-key-client-secret-1
type: Opaque
data:
client1: cGFzc3dvcmQ=
client2: N2ViNDMwOGItY2Q1Yi00NDEzLWI0NTUtYjMyZmQ4OTg2MmZk
7 changes: 7 additions & 0 deletions examples/custom-resources/api-key/api-key-secret-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: api-key-client-secret-2
type: Opaque
data:
client1: cGFzc3dvcmQ=
8 changes: 8 additions & 0 deletions examples/custom-resources/api-key/cafe-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: cafe-secret
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMakNDQWhZQ0NRREFPRjl0THNhWFdqQU5CZ2txaGtpRzl3MEJBUXNGQURCYU1Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhJVEFmQmdOVkJBb01HRWx1ZEdWeWJtVjBJRmRwWkdkcGRITWdVSFI1SUV4MApaREViTUJrR0ExVUVBd3dTWTJGbVpTNWxlR0Z0Y0d4bExtTnZiU0FnTUI0WERURTRNRGt4TWpFMk1UVXpOVm9YCkRUSXpNRGt4TVRFMk1UVXpOVm93V0RFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ01Ba05CTVNFd0h3WUQKVlFRS0RCaEpiblJsY201bGRDQlhhV1JuYVhSeklGQjBlU0JNZEdReEdUQVhCZ05WQkFNTUVHTmhabVV1WlhoaApiWEJzWlM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcDZLbjdzeTgxCnAwanVKL2N5ayt2Q0FtbHNmanRGTTJtdVpOSzBLdGVjcUcyZmpXUWI1NXhRMVlGQTJYT1N3SEFZdlNkd0kyaloKcnVXOHFYWENMMnJiNENaQ0Z4d3BWRUNyY3hkam0zdGVWaVJYVnNZSW1tSkhQUFN5UWdwaW9iczl4N0RsTGM2SQpCQTBaalVPeWwwUHFHOVNKZXhNVjczV0lJYTVyRFZTRjJyNGtTa2JBajREY2o3TFhlRmxWWEgySTVYd1hDcHRDCm42N0pDZzQyZitrOHdnemNSVnA4WFprWldaVmp3cTlSVUtEWG1GQjJZeU4xWEVXZFowZXdSdUtZVUpsc202OTIKc2tPcktRajB2a29QbjQxRUUvK1RhVkVwcUxUUm9VWTNyemc3RGtkemZkQml6Rk8yZHNQTkZ4MkNXMGpYa05MdgpLbzI1Q1pyT2hYQUhBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFLSEZDY3lPalp2b0hzd1VCTWRMClJkSEliMzgzcFdGeW5acS9MdVVvdnNWQTU4QjBDZzdCRWZ5NXZXVlZycTVSSWt2NGxaODFOMjl4MjFkMUpINnIKalNuUXgrRFhDTy9USkVWNWxTQ1VwSUd6RVVZYVVQZ1J5anNNL05VZENKOHVIVmhaSitTNkZBK0NuT0Q5cm4yaQpaQmVQQ0k1ckh3RVh3bm5sOHl3aWozdnZRNXpISXV5QmdsV3IvUXl1aTlmalBwd1dVdlVtNG52NVNNRzl6Q1Y3ClBwdXd2dWF0cWpPMTIwOEJqZkUvY1pISWc4SHc5bXZXOXg5QytJUU1JTURFN2IvZzZPY0s3TEdUTHdsRnh2QTgKN1dqRWVxdW5heUlwaE1oS1JYVmYxTjM0OWVOOThFejM4Zk9USFRQYmRKakZBL1BjQytHeW1lK2lHdDVPUWRGaAp5UkU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcWVpcCs3TXZOYWRJN2lmM01wUHJ3Z0pwYkg0N1JUTnBybVRTdENyWG5LaHRuNDFrCkcrZWNVTldCUU5semtzQndHTDBuY0NObzJhN2x2S2wxd2k5cTIrQW1RaGNjS1ZSQXEzTVhZNXQ3WGxZa1YxYkcKQ0pwaVJ6ejBza0lLWXFHN1BjZXc1UzNPaUFRTkdZMURzcGRENmh2VWlYc1RGZTkxaUNHdWF3MVVoZHErSkVwRwp3SStBM0kreTEzaFpWVng5aU9WOEZ3cWJRcCt1eVFvT05uL3BQTUlNM0VWYWZGMlpHVm1WWThLdlVWQ2cxNWhRCmRtTWpkVnhGbldkSHNFYmltRkNaYkp1dmRySkRxeWtJOUw1S0Q1K05SQlAvazJsUkthaTAwYUZHTjY4NE93NUgKYzMzUVlzeFR0bmJEelJjZGdsdEkxNURTN3lxTnVRbWF6b1Z3QndJREFRQUJBb0lCQVFDUFNkU1luUXRTUHlxbApGZlZGcFRPc29PWVJoZjhzSStpYkZ4SU91UmF1V2VoaEp4ZG01Uk9ScEF6bUNMeUw1VmhqdEptZTIyM2dMcncyCk45OUVqVUtiL1ZPbVp1RHNCYzZvQ0Y2UU5SNThkejhjbk9SVGV3Y290c0pSMXBuMWhobG5SNUhxSkpCSmFzazEKWkVuVVFmY1hackw5NGxvOUpIM0UrVXFqbzFGRnM4eHhFOHdvUEJxalpzVjdwUlVaZ0MzTGh4bndMU0V4eUZvNApjeGI5U09HNU9tQUpvelN0Rm9RMkdKT2VzOHJKNXFmZHZ5dGdnOXhiTGFRTC94MGtwUTYyQm9GTUJEZHFPZVBXCktmUDV6WjYvMDcvdnBqNDh5QTFRMzJQem9idWJzQkxkM0tjbjMyamZtMUU3cHJ0V2wrSmVPRmlPem5CUUZKYk4KNHFQVlJ6NWhBb0dCQU50V3l4aE5DU0x1NFArWGdLeWNrbGpKNkY1NjY4Zk5qNUN6Z0ZScUowOXpuMFRsc05ybwpGVExaY3hEcW5SM0hQWU00MkpFUmgySi9xREZaeW5SUW8zY2czb2VpdlVkQlZHWTgrRkkxVzBxZHViL0w5K3l1CmVkT1pUUTVYbUdHcDZyNmpleHltY0ppbS9Pc0IzWm5ZT3BPcmxEN1NQbUJ2ek5MazRNRjZneGJYQW9HQkFNWk8KMHA2SGJCbWNQMHRqRlhmY0tFNzdJbUxtMHNBRzR1SG9VeDBlUGovMnFyblRuT0JCTkU0TXZnRHVUSnp5K2NhVQprOFJxbWRIQ2JIelRlNmZ6WXEvOWl0OHNaNzdLVk4xcWtiSWN1YytSVHhBOW5OaDFUanNSbmU3NFowajFGQ0xrCmhIY3FIMHJpN1BZU0tIVEU4RnZGQ3haWWRidUI4NENtWmlodnhicFJBb0dBSWJqcWFNWVBUWXVrbENkYTVTNzkKWVNGSjFKelplMUtqYS8vdER3MXpGY2dWQ0thMzFqQXdjaXowZi9sU1JxM0hTMUdHR21lemhQVlRpcUxmZVpxYwpSMGlLYmhnYk9jVlZrSkozSzB5QXlLd1BUdW14S0haNnpJbVpTMGMwYW0rUlk5WUdxNVQ3WXJ6cHpjZnZwaU9VCmZmZTNSeUZUN2NmQ21mb09oREN0enVrQ2dZQjMwb0xDMVJMRk9ycW40M3ZDUzUxemM1em9ZNDR1QnpzcHd3WU4KVHd2UC9FeFdNZjNWSnJEakJDSCtULzZzeXNlUGJKRUltbHpNK0l3eXRGcEFOZmlJWEV0LzQ4WGY2ME54OGdXTQp1SHl4Wlp4L05LdER3MFY4dlgxUE9ucTJBNWVpS2ErOGpSQVJZS0pMWU5kZkR1d29seHZHNmJaaGtQaS80RXRUCjNZMThzUUtCZ0h0S2JrKzdsTkpWZXN3WEU1Y1VHNkVEVXNEZS8yVWE3ZlhwN0ZjanFCRW9hcDFMU3crNlRYcDAKWmdybUtFOEFSek00NytFSkhVdmlpcS9udXBFMTVnMGtKVzNzeWhwVTl6WkxPN2x0QjBLSWtPOVpSY21Vam84UQpjcExsSE1BcWJMSjhXWUdKQ2toaVd4eWFsNmhZVHlXWTRjVmtDMHh0VGwvaFVFOUllTktvCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
26 changes: 26 additions & 0 deletions examples/custom-resources/api-key/cafe-virtual-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: cafe
spec:
host: cafe.example.com
tls:
secret: cafe-secret
policies:
- name: api-key-policy
upstreams:
- name: tea
service: tea-svc
port: 80
- name: coffee
service: coffee-svc
port: 80
routes:
- path: /tea
action:
pass: tea
- path: /coffee
action:
pass: coffee
policies:
- name: api-key-policy-2
65 changes: 65 additions & 0 deletions examples/custom-resources/api-key/cafe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 1
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tea-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: tea
3 changes: 3 additions & 0 deletions internal/configs/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,9 @@ func (cnf *Configurator) AddOrUpdateSecret(secret *api_v1.Secret) string {
case secrets.SecretTypeOIDC:
// OIDC ClientSecret is not required on the filesystem, it is written directly to the config file.
return ""
case api_v1.SecretTypeOpaque:
glog.Infof(secret.Name)
return ""
default:
return cnf.addOrUpdateTLSSecret(secret)
}
Expand Down
25 changes: 25 additions & 0 deletions internal/configs/njs/apikey_auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const c = require("crypto");

function hash(r) {
const header_query_value = r.variables.header_query_value;
const hashed_value = c
.createHash("sha256")
.update(header_query_value)
.digest("hex");
return hashed_value;
}

function validate(r) {
const client_name = r.variables["apikey_auth_local_map"];
const header_query_value = r.variables.header_query_value;

if (!header_query_value) {
r.return(401, "401");
} else if (!client_name) {
r.return(403, "403");
} else {
r.return(204, "204");
}
}

export default { validate, hash };
4 changes: 2 additions & 2 deletions internal/configs/version1/nginx-plus.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ load_module modules/ngx_fips_check_module.so;
{{$value}}{{end}}
{{- end}}

{{- if .OIDC}}
load_module modules/ngx_http_js_module.so;
{{- end}}
oseoin marked this conversation as resolved.
Show resolved Hide resolved

events {
worker_connections {{.WorkerConnections}};
Expand All @@ -41,6 +39,8 @@ http {
map_hash_max_size {{.MapHashMaxSize}};
map_hash_bucket_size {{.MapHashBucketSize}};

js_import /etc/nginx/njs/apikey_auth.js; # TODO: only import if its needed

{{- if .HTTPSnippets}}
{{range $value := .HTTPSnippets}}
{{$value}}{{end}}
Expand Down
6 changes: 6 additions & 0 deletions internal/configs/version1/nginx.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{- /*gotype: github.com/nginxinc/kubernetes-ingress/internal/configs/version1.MainConfig*/ -}}

worker_processes {{.WorkerProcesses}};
{{- if .WorkerRlimitNofile}}
worker_rlimit_nofile {{.WorkerRlimitNofile}};{{end}}
Expand All @@ -20,6 +21,8 @@ load_module modules/ngx_http_opentracing_module.so;
{{$value}}{{end}}
{{- end}}

load_module modules/ngx_http_js_module.so;

events {
worker_connections {{.WorkerConnections}};
}
Expand All @@ -30,6 +33,9 @@ http {
map_hash_max_size {{.MapHashMaxSize}};
map_hash_bucket_size {{.MapHashBucketSize}};


js_import /etc/nginx/njs/apikey_auth.js; # TODO: only import if its needed

{{- if .HTTPSnippets}}
{{range $value := .HTTPSnippets}}
{{$value}}{{end}}
Expand Down
15 changes: 15 additions & 0 deletions internal/configs/version2/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
IngressMTLS *IngressMTLS
EgressMTLS *EgressMTLS
OIDC *OIDC
APIKey *APIKey
WAF *WAF
Dos *Dos
PoliciesErrorReturn *Return
Expand Down Expand Up @@ -137,6 +138,19 @@
AccessTokenEnable bool
}

type APIKey struct {

Check failure on line 141 in internal/configs/version2/http.go

View workflow job for this annotation

GitHub Actions / Lint

exported: exported type APIKey should have comment or be unexported (revive)
Header []string
Query []string
RejectCodeNotSupplied int
RejectCodeNoMatch int
Clients []Client
}

type Client struct {

Check failure on line 149 in internal/configs/version2/http.go

View workflow job for this annotation

GitHub Actions / Lint

exported: exported type Client should have comment or be unexported (revive)
ClientID string
EncryptedKey string
}

// WAF defines WAF configuration.
type WAF struct {
Enable string
Expand Down Expand Up @@ -197,6 +211,7 @@
BasicAuth *BasicAuth
EgressMTLS *EgressMTLS
OIDC bool
APIKey *APIKey
WAF *WAF
Dos *Dos
PoliciesErrorReturn *Return
Expand Down
Loading
Loading