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

Add JWT-validation for idporten/maskinporten #589

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion api/v1alpha1/digdirator/idporten.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package digdirator

import nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1"
import (
"github.com/kartverket/skiperator/api/v1alpha1/istiotypes"
nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1"
)

// Based off NAIS' IDPorten specification as seen here:
// https://github.com/nais/liberator/blob/c9da4cf48a52c9594afc8a4325ff49bbd359d9d2/pkg/apis/nais.io/v1/naiserator_types.go#L93C10-L93C10
Expand Down Expand Up @@ -75,4 +78,7 @@ type IDPorten struct {
// +kubebuilder:validation:Minimum=3600
// +kubebuilder:validation:Maximum=7200
SessionLifetime *int `json:"sessionLifetime,omitempty"`

// Authentication specifies how incoming JWT's should be validated.
Authentication *istiotypes.Authentication `json:"authentication,omitempty"`
}
8 changes: 7 additions & 1 deletion api/v1alpha1/digdirator/maskinporten.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package digdirator

import nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1"
import (
"github.com/kartverket/skiperator/api/v1alpha1/istiotypes"
nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1"
)

// https://github.com/nais/liberator/blob/c9da4cf48a52c9594afc8a4325ff49bbd359d9d2/pkg/apis/nais.io/v1/naiserator_types.go#L376
//
Expand All @@ -15,4 +18,7 @@ type Maskinporten struct {

// Schema to configure Maskinporten clients with consumed scopes and/or exposed scopes.
Scopes *nais_io_v1.MaskinportenScope `json:"scopes,omitempty"`

// Authentication specifies how incoming JWT's should be validated.
Authentication *istiotypes.Authentication `json:"authentication,omitempty"`
}
11 changes: 11 additions & 0 deletions api/v1alpha1/digdirator/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions api/v1alpha1/istiotypes/jwt_authentication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package istiotypes

// Authentication specifies how incoming JWT's should be validated.
//
// +kubebuilder:object:generate=true
type Authentication struct {
// Whether to enable JWT validation.
// If enabled, incoming JWT's will be validated against the issuer specified in the app registration and the generated audience.
Enabled bool `json:"enabled"`

// The name of the kubernetes Secret containing OAuth2-credentials.
//
// If omitted, the associated client registration in the application manifest is used for JWT validation.
SecretName *string `json:"secretName,omitempty"`

// If set to true, the original token will be kept for the upstream request. Default is true.
ForwardOriginalToken *bool `json:"forwardOriginalToken,omitempty"`

// Where to find the JWT in the incoming request
//
// An enum value of `header` means that the JWT is present in the `Authorization` as a Bearer Token.
// An enum value of `cookie` means that the JWT is present as a cookie called `BearerToken`.
//
// +kubebuilder:validation:Enum=header;cookie
TokenLocation *string `json:"tokenLocation,omitempty"`
larsore marked this conversation as resolved.
Show resolved Hide resolved

// This field specifies a list of operations to copy the claim to HTTP headers on a successfully verified token.
// The header specified in each operation in the list must be unique. Nested claims of type string/int/bool is supported as well.
// ```
//
// outputClaimToHeaders:
// - header: x-my-company-jwt-group
// claim: my-group
// - header: x-test-environment-flag
// claim: test-flag
// - header: x-jwt-claim-group
// claim: nested.key.group
//
// ```
OutputClaimToHeaders *[]ClaimToHeader `json:"outputClaimToHeaders,omitempty"`
larsore marked this conversation as resolved.
Show resolved Hide resolved

// IgnorePaths specifies paths that do not require an authenticated JWT.
//
// The specified paths must start with '/'.
// +listType=set
// +kubebuilder:validation:Items.Pattern="^/"
// +kubebuilder:validation:MaxItems=50
IgnorePaths *[]string `json:"ignorePaths,omitempty"`
}

type ClaimToHeader struct {
// The name of the HTTP-header for which the specified claim will be copied to.
Header string `json:"header"`

// The claim to be copied.
Claim string `json:"claim"`
}
48 changes: 48 additions & 0 deletions api/v1alpha1/istiotypes/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

130 changes: 130 additions & 0 deletions config/crd/skiperator.kartverket.no_applications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,71 @@ spec:
maximum: 3600
minimum: 1
type: integer
authentication:
description: Authentication specifies how incoming JWT's should
be validated.
properties:
enabled:
description: |-
Whether to enable JWT validation.
If enabled, incoming JWT's will be validated against the issuer specified in the app registration and the generated audience.
type: boolean
forwardOriginalToken:
description: If set to true, the original token will be kept
for the upstream request. Default is true.
type: boolean
ignorePaths:
description: |-
IgnorePaths specifies paths that do not require an authenticated JWT.

The specified paths must start with '/'.
items:
type: string
maxItems: 50
type: array
x-kubernetes-list-type: set
outputClaimToHeaders:
description: "This field specifies a list of operations to
copy the claim to HTTP headers on a successfully verified
token.\nThe header specified in each operation in the list
must be unique. Nested claims of type string/int/bool is
supported as well.\n```\n\n\toutputClaimToHeaders:\n\t-
header: x-my-company-jwt-group\n\t claim: my-group\n\t-
header: x-test-environment-flag\n\t claim: test-flag\n\t-
header: x-jwt-claim-group\n\t claim: nested.key.group\n\n```"
items:
properties:
claim:
description: The claim to be copied.
type: string
header:
description: The name of the HTTP-header for which the
specified claim will be copied to.
type: string
required:
- claim
- header
type: object
type: array
secretName:
description: |-
The name of the kubernetes Secret containing OAuth2-credentials.

If omitted, the associated client registration in the application manifest is used for JWT validation.
type: string
tokenLocation:
description: |-
Where to find the JWT in the incoming request

An enum value of `header` means that the JWT is present in the `Authorization` as a Bearer Token.
An enum value of `cookie` means that the JWT is present as a cookie called `BearerToken`.
enum:
- header
- cookie
type: string
required:
- enabled
type: object
clientName:
description: |-
The name of the Client as shown in Digitaliseringsdirektoratet's Samarbeidsportal
Expand Down Expand Up @@ -756,6 +821,71 @@ spec:
maskinporten:
description: Settings for Maskinporten integration with Digitaliseringsdirektoratet
properties:
authentication:
description: Authentication specifies how incoming JWT's should
be validated.
properties:
enabled:
description: |-
Whether to enable JWT validation.
If enabled, incoming JWT's will be validated against the issuer specified in the app registration and the generated audience.
type: boolean
forwardOriginalToken:
description: If set to true, the original token will be kept
for the upstream request. Default is true.
type: boolean
ignorePaths:
description: |-
IgnorePaths specifies paths that do not require an authenticated JWT.

The specified paths must start with '/'.
items:
type: string
maxItems: 50
type: array
x-kubernetes-list-type: set
outputClaimToHeaders:
description: "This field specifies a list of operations to
copy the claim to HTTP headers on a successfully verified
token.\nThe header specified in each operation in the list
must be unique. Nested claims of type string/int/bool is
supported as well.\n```\n\n\toutputClaimToHeaders:\n\t-
header: x-my-company-jwt-group\n\t claim: my-group\n\t-
header: x-test-environment-flag\n\t claim: test-flag\n\t-
header: x-jwt-claim-group\n\t claim: nested.key.group\n\n```"
items:
properties:
claim:
description: The claim to be copied.
type: string
header:
description: The name of the HTTP-header for which the
specified claim will be copied to.
type: string
required:
- claim
- header
type: object
type: array
secretName:
description: |-
The name of the kubernetes Secret containing OAuth2-credentials.

If omitted, the associated client registration in the application manifest is used for JWT validation.
type: string
tokenLocation:
description: |-
Where to find the JWT in the incoming request

An enum value of `header` means that the JWT is present in the `Authorization` as a Bearer Token.
An enum value of `cookie` means that the JWT is present as a cookie called `BearerToken`.
enum:
- header
- cookie
type: string
required:
- enabled
type: object
clientName:
description: |-
The name of the Client as shown in Digitaliseringsdirektoratet's Samarbeidsportal
Expand Down
Loading
Loading