Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Kubernetes Operator for automated registration and configuration of Digdir clients (ID-porten & Maskinporten)

License

NotificationsYou must be signed in to change notification settings

nais/digdirator

Repository files navigation

Digdirator is a Kubernetes operator for declarative registration and lifecycle management ofvarious resources withinDigdir throughitsself-service API.It currently supports:

CRDs

The operator uses two custom resource definitions (CRDs):

IDPortenClient

apiVersion:nais.io/v1kind:IDPortenClientmetadata:name:my-appnamespace:my-teamspec:clientURI:"https://domain.example"frontchannelLogoutURI:"https://domain.example/oauth2/logout/frontchannel"redirectURIs:    -"https://domain.example/oauth2/callback"postLogoutRedirectURIs:    -"https://domain.example/oauth2/logout/callback"secretName:my-secret

For the full CRD specification with all possible options, seenais/liberator/config/crd/nais.io_idportenclients.yaml

AnIDPortenClient resource contains:

  • the client configuration
  • the name of the Kubernetes secret that the application expects to contain the client's credentials

The Kubernetes secret contains the following keys:

KeyDescription
IDPORTEN_CLIENT_IDThe application's client ID.
IDPORTEN_CLIENT_JWKThe application's private JSON Web Key (JWK) for client authentication (RFC 7523, section 2.2).
IDPORTEN_WELL_KNOWN_URLThe URL pointing to the ID-porten's well-known metadata document.
IDPORTEN_ISSUERTheissuer property from the metadata document.
IDPORTEN_JWKS_URIThejwks_uri property from the metadata document.
IDPORTEN_TOKEN_ENDPOINTThetoken_endpoint property from the metadata document.

MaskinportenClient

---apiVersion:nais.io/v1kind:MaskinportenClientmetadata:name:my-appnamespace:my-teamspec:secretName:my-secretscopes:exposes:# results in the fully qualified scope name:# `prefix:product:some/scope`      -product:"product"name:"some/scope"enabled:trueconsumers:          -orgno:"889640782"consumes:      -name:"prefix:some/api.read"

For the full CRD specification with all possible options, seeconfig/crd/nais.io_maskinportenclients.yaml

AMaskinportenClient resource contains:

  • a list of scopes the applicationconsumes or needs access to (optional)
  • a list of scopes the applicationexposes (optional)
    • note: this will be extracted to its own CRD at some point
  • the name of the Kubernetes secret that the application expects to contain the client's credentials

The Kubernetes secret contains the following keys:

KeyDescription
MASKINPORTEN_CLIENT_IDThe application's client ID.
MASKINPORTEN_CLIENT_JWKThe application's private JSON Web Key (JWK) for client authentication (RFC 7523, section 2.2).
MASKINPORTEN_WELL_KNOWN_URLThe URL pointing to Maskinporten's well-known metadata document.
MASKINPORTEN_ISSUERTheissuer property from the metadata document.
MASKINPORTEN_JWKS_URIThejwks_uri property from the metadata document.
MASKINPORTEN_TOKEN_ENDPOINTThetoken_endpoint property from the metadata document.

Lifecycle

sequenceDiagram    actor developer as Developer or<br/>Operator    box rgba(33,66,99,0.5) Kubernetes Cluster        participant crd as IDPortenClient or<br/>MaskinportenClient        participant secrets as Secrets        participant digdirator as Digdirator    end    participant kms as Google Cloud KMS    participant digdir as Digdir Admin API    loop forever      digdirator ->> crd: watches    end    developer ->> crd: apply resource    digdirator ->> crd: get resource    crd ->> secrets: owns    digdirator ->> secrets: get all owned by resource    alt `spec.secretName` has changed      digdirator ->> digdirator: create new private key    else `spec.secretName` is unchanged      digdirator ->> digdirator: re-use private key from existing secret    end    loop for each API request      digdirator ->> digdirator: create client assertion      digdirator ->> kms: sign client assertion    end    digdirator ->> digdir: create/update client    digdirator ->> digdir: create/update client jwks    alt if exposes maskinporten scopes      digdirator ->> digdir: create/update scopes      digdirator ->> digdir: add/remove consumers    end    digdirator ->> secrets: create/update    loop for each owned secret      alt name equals `spec.secretName`        digdirator ->> secrets: keep secret      else        digdirator ->> secrets: delete if<br/>unreferenced      end    end
Loading
  1. When anIDPortenClient or aMaskinportenClient resource is applied to the cluster (either by a developer or another operator), the Digdirator controller will reconcile it.
  2. Digdirator reads the resource and retrieves all existing secrets owned by the resource.
  3. Digdirator then checks if thespec.secretName has changed:
    1. If the secret name has changed, it creates a new private key for the application.
    2. If the secret name is unchanged, it reuses the private key from the existing secret.
  4. For each request to Digdir's admin API, Digdirator creates a client assertion for authentication.
  5. The application's configuration and public keys (JWKS) are registered/updated through the API.
    1. The JWKS contains all currently used public keys to ensure key rotation works properly.
    2. If theMaskinportenClient resource exposes Maskinporten scopes, these are also registered/updated. Consumers are added/removed as needed.
  6. The operator creates or updates the Kubernetes secret with the specifiedspec.secretName.
  7. Finally, any unreferenced secrets are deleted to clean up resources.
    1. Secrets are considered referenced if mounted as files or environment variables in aPod.ThePod must have a labelapp=<name> where<name> is equal to.metadata.name in theIDPortenClient orMaskinportenClient resource.

Usage

Installation

make install

Digdir Setup

See the documentation over at Digdir for acquiring clients with the required scopes to access the self-service APIs:

Digdirator uses a single privileged client for administration of ID-porten and Maskinporten clients.It authenticates itself with the DigDir self-service APIs by using a JWT grant signed with the configured business certificate.

Google Cloud Platform Setup

Digdirator currently depends on a Google Cloud Platform product, namely Cloud Key Management Service (KMS).The KMS is used to store the private key belonging to the business certificate.These are needed for authenticating the DigDir client with Maskinporten using the JWT-bearer authorization grant.

You should set upWorkload Identity for your GKE cluster.

Digdirator needs a Google IAM Service Account to access the GCP resources.With Workload Identity, this should work automagically as we use Google's libraries that should automatically pick up the Kubernetes Service Account tokens and perform the necessary exchanges.

Cloud KMS

The Google Service Account needs the following IAM role for eachkey in Cloud KMS:

  • Cloud KMS CryptoKey Signer/Verifier (roles/cloudkms.signerVerifier)

FollowGoogle's documentation for importing keys.

The private key should be imported with the purpose set toASYMMETRIC_SIGN, and the algorithm set to one of theRSASSA-PKCS1 v1_5 variants.

Configuration

Digdirator can be configured using command-line flags:

FlagTypeDefault ValueDescription
--cluster-namestringThe cluster in which this application should run.
--development-modestringfalseToggle for development mode.
--digdir.admin.base-urlstringBase URL endpoint for interacting with DigDir self service API.
--digdir.admin.cert-chainstringFull certificate chain in PEM format for business certificate used to sign JWT assertion.
--digdir.admin.client-idstringClient ID / issuer for JWT assertion when authenticating with DigDir self service API.
--digdir.admin.kms-key-pathstringResource path to Google KMS key used to sign JWT assertion.
--digdir.admin.scopesstringidporten:dcr.write idporten:dcr.read idporten:scopes.writeList of space-separated scopes for JWT assertion when authenticating with DigDir self service API.
--digdir.common.access-token-lifetimeint3600Default lifetime (in seconds) for access tokens for all clients.
--digdir.common.client-namestringARBEIDS- OG VELFERDSETATENDefault name for all provisioned clients. Appears in the login prompt for ID-porten.
--digdir.common.client-uristringhttps://www.nav.noDefault client URI for all provisioned clients. Appears in the back-button for the login prompt for ID-porten.
--digdir.common.session-lifetimeint7200Default lifetime (in seconds) for sessions (authorization and refresh token lifetime) for all clients.
--digdir.idporten.well-known-urlstringURL toID-porten well-known discovery metadata document.
--digdir.maskinporten.default.client-scopestringnav:test/apiDefault scope for provisioned Maskinporten clients, if none specified in spec.
--digdir.maskinporten.default.scope-prefixstringnavDefault scope prefix for provisioned Maskinporten scopes.
--digdir.maskinporten.well-known-urlstringURL toMaskinporten well-known discovery metadata document.
--features.maskinportenbooleanfalseFeature toggle for maskinporten.
--leader-election.enabledbooleanfalseToggle for enabling leader election.
--leader-election.namespacestringNamespace for the leader election resource. Needed if not running in-cluster (e.g. locally).
--metrics-addressstring:8080The address the metric endpoint binds to.

At minimum, the following configuration must be provided:

  • cluster-name
  • digdir.admin.base-url
  • digdir.admin.cert-chain
  • digdir.admin.client-id
  • digdir.admin.kms-key-path
  • digdir.admin.scopes
  • digdir.idporten.well-known-url
  • digdir.maskinporten.well-known-url

The properties can also be set using environment variables using the following convention:

  • convert to uppercase
  • replace dashes (-) and dots (.) with underscores (_)
  • prefix the property withDIGDIRATOR_

For example:

digdir.admin.base-url -> DIGDIRATOR_ADMIN_BASE_URL

Properties can also be specified using JSON, TOML or YAML config files.Digdirator looks for a file nameddigdirator.<ext> in the directories [.,/etc/].

Example configuration in YAML:

# ./digdirator.yamlcluster-name:localdevelopment-mode:truefeatures:maskinporten:truedigdir:admin:base-url:"https://api.test.samarbeid.digdir.no"client-id:"some-client-id"cert-chain:|-      -----BEGIN CERTIFICATE-----      MII...      -----END CERTIFICATE-----kms-key-path:"projects/<project-id>/locations/<location>/keyRings/<key-ring-name>/cryptoKeys/<key-name>/cryptoKeyVersions/<key-version>"scopes:"idporten:dcr.write idporten:dcr.read idporten:scopes.write"idporten:well-known-url:"https://test.idporten.no/idporten-oidc-provider/.well-known/openid-configuration"maskinporten:well-known-url:"https://test.maskinporten.no/.well-known/oauth-authorization-server"

Development

If you're running locally, make sure you have access to the GCP resources and that you're authenticated with Application Default Credentials:

gcloud auth login --update-adc

Then, assuming you have a Kubernetes cluster running locally (e.g.usingminikube):

ulimit -n 4096# for controller-genmake runmake sample

Verifying the Digdirator image and its contents

The image is signed "keylessly" (is that a word?) usingSigstore cosign.To verify its authenticity run

cosign verify \--certificate-identity "https://github.com/nais/digdirator/.github/workflows/build.yml@refs/heads/master" \--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ghcr.io/nais/digdirator@sha256:<shasum>

The images are also attested with SBOMs in theCycloneDX format.You can verify these by running

cosign verify-attestation --type cyclonedx \--certificate-identity "https://github.com/nais/digdirator/.github/workflows/build.yml@refs/heads/master" \--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ghcr.io/nais/digdirator@sha256:<shasum>

About

Kubernetes Operator for automated registration and configuration of Digdir clients (ID-porten & Maskinporten)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors14

Languages


[8]ページ先頭

©2009-2025 Movatter.jp