-
Notifications
You must be signed in to change notification settings - Fork 143
Enhancement Proposal: Authentication Filter #4235
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
d91a5f4
9047c3e
c937366
1b8bac2
2f143e9
61f479c
47ff38b
40b8224
24966b8
ecceb93
da1b17e
38dd8f7
e362745
dd5aaa8
bf3ed2b
eb49b32
a86a3ae
79b957d
e0ec4fb
d3ebed4
4f1c893
5ff7389
dd24287
14b84a9
8526c7f
93486eb
d91b389
b6fb76b
73594af
7aede4c
acbb54c
4aae8e7
1029c3e
c864630
ef57f2a
22d2726
9e6b3c9
21b5611
65c1adc
a0c8c04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -136,11 +136,8 @@ const ( | |||||||||||
|
|
||||||||||||
| // BasicAuth configures HTTP Basic Authentication. | ||||||||||||
| type BasicAuth struct { | ||||||||||||
| // SecretRef allows referencing a Secret in the same or different namespace. | ||||||||||||
| // When namespace is set and differs from the filter's namespace, a ReferenceGrant in the target namespace is required. | ||||||||||||
| // | ||||||||||||
| // +optional | ||||||||||||
| SecretRef *SecretObjectReference `json:"secretRef,omitempty"` | ||||||||||||
| // SecretRef allows referencing a Secret in the same namespace | ||||||||||||
| SecretRef LocalObjectReferenceWithKey `json:"secretRef,omitempty"` | ||||||||||||
|
|
||||||||||||
| // Realm used by NGINX `auth_basic` directive. | ||||||||||||
| // https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic | ||||||||||||
|
|
@@ -230,7 +227,7 @@ type JWTAuth struct { | |||||||||||
| // FileKeySource specifies local JWKS key configuration. | ||||||||||||
| type FileKeySource struct { | ||||||||||||
| // SecretRef references a Secret containing the JWKS. | ||||||||||||
| SecretRef SecretObjectReference `json:"secretRef,omitempty"` | ||||||||||||
| SecretRef LocalObjectReferenceWithKey `json:"secretRef,omitempty"` | ||||||||||||
|
|
||||||||||||
| // KeyCache is the cache duration for keys. | ||||||||||||
| // Configures `auth_jwt_key_cache` directive. | ||||||||||||
|
|
@@ -241,6 +238,13 @@ type FileKeySource struct { | |||||||||||
| KeyCache *v1alpha1.Duration `json:"keyCache,omitempty"` | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // LocalObjectReferenceWithKey sepcifies as local kubernetes object | ||||||||||||
| // with required `key` field to extract data. | ||||||||||||
| type LocalObjectReferenceWithKey struct { | ||||||||||||
| v1.LocalObjectReference | ||||||||||||
| Key string | ||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we set a default key that we can use in our docs so users don't have to specify this unless they explicitly change it. |
||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // RemoteKeySource specifies remote JWKS configuration. | ||||||||||||
| type RemoteKeySource struct { | ||||||||||||
| // URL is the JWKS endpoint, e.g. "https://issuer.example.com/.well-known/jwks.json". | ||||||||||||
|
|
@@ -395,6 +399,7 @@ spec: | |||||||||||
| basic: | ||||||||||||
| secretRef: | ||||||||||||
| name: basic-auth-users # Secret containing htpasswd data | ||||||||||||
| key: htpasswd | ||||||||||||
| realm: "Restricted" # Optional. Helps with logging | ||||||||||||
| onFailure: # Optional. These setting may be defaults. | ||||||||||||
| statusCode: 401 | ||||||||||||
|
|
@@ -512,6 +517,7 @@ spec: | |||||||||||
| file: | ||||||||||||
| secretRef: | ||||||||||||
| name: jwt-keys-secure | ||||||||||||
| key: jwks.json | ||||||||||||
| keyCache: 10m # Optional cache time for keys (auth_jwt_key_cache) | ||||||||||||
| # Acceptable clock skew for exp/nbf | ||||||||||||
| leeway: 60s # Configures auth_jwt_leeway | ||||||||||||
|
|
@@ -859,52 +865,6 @@ Users that attach an `AuthenticationFilter` to an HTTPRoute/GRPCRoute should be | |||||||||||
|
|
||||||||||||
| Any example configurations and deployments for the `AuthenticationFilter` should enable HTTPS at the Gateway level by default. | ||||||||||||
|
|
||||||||||||
| ### Namespace isolataion and cross-namespace references | ||||||||||||
| Both Auth and Local JWKS should only have access to Secrets and ConfigMaps in the same namespace by default. | ||||||||||||
|
|
||||||||||||
| Cross-namespace references are allowed only when authorized via a Gateway API ReferenceGrant in the target namespace. | ||||||||||||
|
|
||||||||||||
| Controller behavior: | ||||||||||||
| - Same-namespace references are permitted without a grant. | ||||||||||||
| - For cross-namespace references, the controller MUST verify a ReferenceGrant exists in the target namespace: | ||||||||||||
| - from: group=gateway.nginx.org, kind=AuthenticationFilter, namespace=<filter-namespace> | ||||||||||||
| - to: group="", kind=(Secret|ConfigMap), name=<target-name> | ||||||||||||
| - If no valid grant is found, the filter status should update the status to `Accepted=False` with `reason=RefNotPermitted` and a clear message. We should avoid rendering any NGINX configuration in this scenario. | ||||||||||||
|
|
||||||||||||
| Example: Grant BasicAuth in app-ns to read a Secret in security-ns | ||||||||||||
| ```yaml | ||||||||||||
| apiVersion: gateway.networking.k8s.io/v1 | ||||||||||||
| kind: ReferenceGrant | ||||||||||||
| metadata: | ||||||||||||
| name: allow-basic-auth-secret | ||||||||||||
| namespace: security-ns # target namespace where the Secret lives | ||||||||||||
| spec: | ||||||||||||
| from: | ||||||||||||
| - group: gateway.nginx.org | ||||||||||||
| kind: AuthenticationFilter | ||||||||||||
| namespace: app-ns | ||||||||||||
| to: | ||||||||||||
| - group: "" # core API group | ||||||||||||
| kind: Secret | ||||||||||||
| name: basic-auth-users | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| AuthenticationFilter referencing the cross-namespace Secret | ||||||||||||
| ```yaml | ||||||||||||
| apiVersion: gateway.nginx.org/v1alpha1 | ||||||||||||
| kind: AuthenticationFilter | ||||||||||||
| metadata: | ||||||||||||
| name: basic-auth | ||||||||||||
| namespace: app-ns | ||||||||||||
| spec: | ||||||||||||
| type: Basic | ||||||||||||
| basic: | ||||||||||||
| secretRef: | ||||||||||||
| namespace: security-ns | ||||||||||||
| name: basic-auth-users | ||||||||||||
| realm: "Restricted" | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Remote JWKS | ||||||||||||
|
|
||||||||||||
| Proxy cache TTL should be configurable and set to a reasonable default, reducing periods of stale cached JWKs. | ||||||||||||
|
|
@@ -981,7 +941,7 @@ document that behavior. | |||||||||||
|
|
||||||||||||
| ## Stretch Goals | ||||||||||||
|
|
||||||||||||
| ### Cross namespace acess | ||||||||||||
| ### Cross namespace access | ||||||||||||
|
|
||||||||||||
| When referencing secrets for Basic Auth and JWT Auth, the initial implementation will use `LocalObjectReference`. | ||||||||||||
|
|
||||||||||||
|
|
@@ -1001,6 +961,42 @@ type NamespacedSecretKeyReference struct { | |||||||||||
| } | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| For initial implementaion, both Basic Auth and Local JWKS should will only have access to Secrets in the same namespace. | ||||||||||||
|
|
||||||||||||
| Example: Grant BasicAuth in app-ns to read a Secret in security-ns | ||||||||||||
| ```yaml | ||||||||||||
|
Comment on lines
+968
to
+969
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| apiVersion: gateway.networking.k8s.io/v1 | ||||||||||||
| kind: ReferenceGrant | ||||||||||||
| metadata: | ||||||||||||
| name: allow-basic-auth-secret | ||||||||||||
| namespace: security-ns # target namespace where the Secret lives | ||||||||||||
| spec: | ||||||||||||
| from: | ||||||||||||
| - group: gateway.nginx.org | ||||||||||||
| kind: AuthenticationFilter | ||||||||||||
| namespace: app-ns | ||||||||||||
| to: | ||||||||||||
| - group: "" # core API group | ||||||||||||
| kind: Secret | ||||||||||||
| name: basic-auth-users | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| AuthenticationFilter referencing the cross-namespace Secret | ||||||||||||
| ```yaml | ||||||||||||
|
Comment on lines
+986
to
+987
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| apiVersion: gateway.nginx.org/v1alpha1 | ||||||||||||
| kind: AuthenticationFilter | ||||||||||||
| metadata: | ||||||||||||
| name: basic-auth | ||||||||||||
| namespace: app-ns | ||||||||||||
| spec: | ||||||||||||
| type: Basic | ||||||||||||
| basic: | ||||||||||||
| secretRef: | ||||||||||||
| namespace: security-ns | ||||||||||||
| name: basic-auth-users | ||||||||||||
| realm: "Restricted" | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Additional Fields for JWT | ||||||||||||
|
|
||||||||||||
| `require`, `tokenSource` and `propagation` are some additional fields that may be incldued in future updates to the API. | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use
SecretRefas the name either, for flexibility.