Skip to content

[FEAT shoot-grafter] - IssuerTargets API #57

@uwe-mayer

Description

@uwe-mayer

Priority

(Medium) I'm annoyed but I'll live

Description

To enhance shoot-grafter with dynamic issuer config we need to spec the API first.

Acceptance criteria

  • .Spec has a new field IssuerTargets as specified below
  • It is well-defined how to do the templating

Out of scope

  • Controller implementation of the API

API

The issuer config allows some CEL expression evaluation to make it dynamic and cluster (metadata) specific. This CEL is delimited by {{}}and evaluated by the controller to differentiate from the CEL evaluated by the k8s api-server at runtime.

// IssuerTarget defines the issuer configuration to register on a target cluster
// when a new shoot is onboarded by this CareInstruction.
// String fields within the JWTAuthenticator support template variable substitution
// using {{...}} syntax. Available variables:
// - {{clusterName}} - name of the newly onboarded Greenhouse Cluster
// - {{cluster.metadata.<meta-data-key>}} - label values of `metadata.greenhouse.sap/<meta-data-key>` from the onboarded Cluster. See https://cloudoperators.github.io/greenhouse/docs/user-guides/plugin/metadata-expressions/
//
// Template variables ({{...}}) are evaluated at reconcile time by shoot-grafter.
// CEL expressions within claimValidationRules are left untouched and evaluated
// at runtime by the target cluster's kube-apiserver.
type IssuerTarget struct {
    // Issuer is the JWTAuthenticator configuration template to register on the target cluster.
    Issuer apiserverv1beta1.JWTAuthenticator `json:"issuer"`
}

// IssuerTargets maps target Greenhouse Cluster names to issuer configurations.
// When a shoot is onboarded as a new Greenhouse Cluster, the specified issuer configuration
// (after {{...}} template variable substitution) will be registered as a trusted issuer
// on each target cluster specified in this map.
// The key is the name of an already-onboarded Greenhouse Cluster where the issuer should be registered.
// +optional
IssuerTargets map[string]IssuerTarget `json:"issuerTargets,omitempty"`

Example:

issuerTargets:
    monitoring-central:
      issuer:
        issuer:
          # {{...}} = resolved by shoot-grafter controller at reconcile time
          url: "https://{{clusterName}}.greenhouse.example.com/oidc"
          audiences:
            - "{{clusterName}}"
        claimMappings:
          username:
            claim: sub
            prefix: '{{clusterName}}:' # enforced by shoot-grafter to prevent user/group impersonation
          groups:
            claim: groups
            prefix: '{{clusterName}}:' # enforced by shoot-grafter to prevent user/group impersonation
        claimValidationRules:
          # The expression field here contains BOTH:
          # - {{...}} resolved by the controller at reconcile time
          # - Example CEL resolved by the kube-apiserver at token validation time
          - expression: "claims.iss == 'https://{{clusterName}}.greenhouse.example.com/oidc'"
            message: "token issuer must match the registered cluster"
          # Example mix in same expression:
          - expression: "'{{cluster.metadata.region}}' in claims.allowed_regions"
            message: "token must be authorized for the cluster's region"

Reference Issues

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogReady for sprint planning; triggers project addition
    No fields configured for Feature.

    Projects

    Status
    Sprint Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions