{
  "description": "JWTAuthenticator describes the configuration of a JWT authenticator.\n\nUpon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid\nsignature, existence of claims, etc.) and extract the username and groups from the token.",
  "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": "string"
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "spec": {
      "description": "spec for configuring the authenticator.",
      "properties": {
        "audience": {
          "description": "audience is the required value of the \"aud\" JWT claim.",
          "minLength": 1,
          "type": "string"
        },
        "claimValidationRules": {
          "description": "claimValidationRules are rules that are applied to validate token claims to authenticate users.\nThis is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in\nhttps://kubernetes.io/docs/reference/access-authn-authz/authentication.\nThis is an advanced configuration option. During an end-user login flow, mistakes in this\nconfiguration will cause the user's login to fail.",
          "items": {
            "description": "ClaimValidationRule provides the configuration for a single claim validation rule.",
            "properties": {
              "claim": {
                "description": "claim is the name of a required claim.\nOnly string claim keys are supported.\nMutually exclusive with expression and message.",
                "type": "string"
              },
              "expression": {
                "description": "expression represents the expression which will be evaluated by CEL.\nMust produce a boolean.\n\nCEL expressions have access to the contents of the token claims, organized into CEL variable:\n- 'claims' is a map of claim names to claim values.\n  For example, a variable named 'sub' can be accessed as 'claims.sub'.\n  Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.\nMust return true for the validation to pass.\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nMutually exclusive with claim and requiredValue.",
                "type": "string"
              },
              "message": {
                "description": "message customizes the returned error message when expression returns false.\nmessage is a literal string.\nMutually exclusive with claim and requiredValue.",
                "type": "string"
              },
              "requiredValue": {
                "description": "requiredValue is the value of a required claim.\nOnly string claim values are supported.\nIf claim is set and requiredValue is not set, the claim must be present with a value set to the empty string.\nMutually exclusive with expression and message.",
                "type": "string"
              }
            },
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "claims": {
          "description": "claims allows customization of the claims that will be mapped to user identity\nfor Kubernetes access.",
          "properties": {
            "extra": {
              "description": "extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration\nas documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.\n\nHowever, note that the Pinniped Concierge issues client certificates to users for the purpose\nof authenticating, and the Kubernetes API server does not have any mechanism for transmitting\nauth extras via client certificates. When configured, these extras will appear in client\ncertificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational\nUnits (OU). However, when this client certificate is presented to Kubernetes for authentication,\nKubernetes will ignore these extras. This is probably only useful if you are using a custom\nauthenticating proxy in front of your Kubernetes API server which can translate these OUs into\nauth extras, as described by\nhttps://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy.\nThis is an advanced configuration option. During an end-user login flow, each of these CEL expressions\nmust evaluate to either a string or an array of strings, or else the user's login will fail.\n\nThese keys must be a domain-prefixed path (such as \"acme.io/foo\") and must not contain an equals sign (\"=\").\n\nexpression must produce a string or string array value.\nIf the value is empty, the extra mapping will not be present.\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nhard-coded extra key/value\n- key: \"acme.io/foo\"\n  valueExpression: \"'bar'\"\nThis will result in an extra attribute - acme.io/foo: [\"bar\"]\n\nhard-coded key, value copying claim value\n- key: \"acme.io/foo\"\n  valueExpression: \"claims.some_claim\"\nThis will result in an extra attribute - acme.io/foo: [value of some_claim]\n\nhard-coded key, value derived from claim value\n- key: \"acme.io/admin\"\n  valueExpression: '(has(claims.is_admin) && claims.is_admin) ? \"true\":\"\"'\nThis will result in:\n - if is_admin claim is present and true, extra attribute - acme.io/admin: [\"true\"]\n - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added",
              "items": {
                "description": "ExtraMapping provides the configuration for a single extra mapping.",
                "properties": {
                  "key": {
                    "description": "key is a string to use as the extra attribute key.\nkey must be a domain-prefix path (e.g. example.org/foo). All characters before the first \"/\" must be a valid\nsubdomain as defined by RFC 1123. All characters trailing the first \"/\" must\nbe valid HTTP Path characters as defined by RFC 3986.\nkey must be lowercase.\nRequired to be unique.\nAdditionally, the key must not contain an equals sign (\"=\").",
                    "type": "string"
                  },
                  "valueExpression": {
                    "description": "valueExpression is a CEL expression to extract extra attribute value.\nvalueExpression must produce a string or string array value.\n\"\", [], and null values are treated as the extra mapping not being present.\nEmpty string values contained within a string array are filtered out.\n\nCEL expressions have access to the contents of the token claims, organized into CEL variable:\n- 'claims' is a map of claim names to claim values.\n  For example, a variable named 'sub' can be accessed as 'claims.sub'.\n  Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/",
                    "type": "string"
                  }
                },
                "required": [
                  "key",
                  "valueExpression"
                ],
                "type": "object",
                "additionalProperties": false
              },
              "type": "array"
            },
            "groups": {
              "description": "groups is the name of the claim which should be read to extract the user's\ngroup membership from the JWT token. When not specified, it will default to \"groups\",\nunless groupsExpression is specified.\n\nMutually exclusive with groupsExpression. Use either groups or groupsExpression to\ndetermine the user's group membership from the JWT token.",
              "type": "string"
            },
            "groupsExpression": {
              "description": "groupsExpression represents an expression which will be evaluated by CEL.\nThe expression's result will become the user's group memberships.\n\ngroupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration\nas documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.\nThis is an advanced configuration option. During an end-user login flow, each of these CEL expressions\nmust evaluate to one of the expected types without errors, or else the user's login will fail.\nAdditionally, mistakes in this configuration can cause the users to have unintended group memberships.\n\nThe expression must produce a string or string array value.\n \"\", [], and null values are treated as the group mapping not being present.\n\nCEL expressions have access to the contents of the token claims, organized into CEL variable:\n- 'claims' is a map of claim names to claim values.\n  For example, a variable named 'sub' can be accessed as 'claims.sub'.\n  Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nMutually exclusive with groups. Use either groups or groupsExpression to\ndetermine the user's group membership from the JWT token.",
              "type": "string"
            },
            "username": {
              "description": "username is the name of the claim which should be read to extract the\nusername from the JWT token. When not specified, it will default to \"username\",\nunless usernameExpression is specified.\n\nMutually exclusive with usernameExpression. Use either username or usernameExpression to\ndetermine the user's username from the JWT token.",
              "type": "string"
            },
            "usernameExpression": {
              "description": "usernameExpression represents an expression which will be evaluated by CEL.\nThe expression's result will become the user's username.\n\nusernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration\nas documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.\nThis is an advanced configuration option. During an end-user login flow, each of these CEL expressions\nmust evaluate to the expected type without errors, or else the user's login will fail.\nAdditionally, mistakes in this configuration can cause the users to have unintended usernames.\n\nThe expression must produce a non-empty string value.\nIf the expression uses 'claims.email', then 'claims.email_verified' must be used in\nthe expression or extra[*].valueExpression or claimValidationRules[*].expression.\nAn example claim validation rule expression that matches the validation automatically\napplied when username.claim is set to 'email' is 'claims.?email_verified.orValue(true) == true'.\nBy explicitly comparing the value to true, we let type-checking see the result will be a boolean,\nand to make sure a non-boolean email_verified claim will be caught at runtime.\n\nCEL expressions have access to the contents of the token claims, organized into CEL variable:\n- 'claims' is a map of claim names to claim values.\n  For example, a variable named 'sub' can be accessed as 'claims.sub'.\n  Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nMutually exclusive with username. Use either username or usernameExpression to\ndetermine the user's username from the JWT token.",
              "type": "string"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "issuer": {
          "description": "issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is\nalso used to validate the \"iss\" JWT claim.",
          "minLength": 1,
          "pattern": "^https://",
          "type": "string"
        },
        "tls": {
          "description": "tls is the configuration for communicating with the OIDC provider via TLS.",
          "properties": {
            "certificateAuthorityData": {
              "description": "X.509 Certificate Authority (base64-encoded PEM bundle). If omitted, a default set of system roots will be trusted.",
              "type": "string"
            },
            "certificateAuthorityDataSource": {
              "description": "Reference to a CA bundle in a secret or a configmap.\nAny changes to the CA bundle in the secret or configmap will be dynamically reloaded.",
              "properties": {
                "key": {
                  "description": "Key is the key name within the secret or configmap from which to read the CA bundle.\nThe value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded\ncertificate bundle.",
                  "minLength": 1,
                  "type": "string"
                },
                "kind": {
                  "description": "Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.\nAllowed values are \"Secret\" or \"ConfigMap\".\n\"ConfigMap\" uses a Kubernetes configmap to source CA Bundles.\n\"Secret\" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.",
                  "enum": [
                    "Secret",
                    "ConfigMap"
                  ],
                  "type": "string"
                },
                "name": {
                  "description": "Name is the resource name of the secret or configmap from which to read the CA bundle.\nThe referenced secret or configmap must be created in the same namespace where Pinniped Concierge is installed.",
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "key",
                "kind",
                "name"
              ],
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "userValidationRules": {
          "description": "userValidationRules are rules that are applied to final user before completing authentication.\nThese allow invariants to be applied to incoming identities such as preventing the\nuse of the system: prefix that is commonly used by Kubernetes components.\nThe validation rules are logically ANDed together and must all return true for the validation to pass.\nThis is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in\nhttps://kubernetes.io/docs/reference/access-authn-authz/authentication.\nThis is an advanced configuration option. During an end-user login flow, mistakes in this\nconfiguration will cause the user's login to fail.",
          "items": {
            "description": "UserValidationRule provides the configuration for a single user info validation rule.",
            "properties": {
              "expression": {
                "description": "expression represents the expression which will be evaluated by CEL.\nMust return true for the validation to pass.\n\nCEL expressions have access to the contents of UserInfo, organized into CEL variable:\n- 'user' - authentication.k8s.io/v1, Kind=UserInfo object\n   Refer to https://github.com/kubernetes/api/blob/release-1.28/authentication/v1/types.go#L105-L122 for the definition.\n   API documentation: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#userinfo-v1-authentication-k8s-io\n\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/",
                "type": "string"
              },
              "message": {
                "description": "message customizes the returned error message when rule returns false.\nmessage is a literal string.",
                "type": "string"
              }
            },
            "required": [
              "expression"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        }
      },
      "required": [
        "audience",
        "issuer"
      ],
      "type": "object",
      "additionalProperties": false
    },
    "status": {
      "description": "status of the authenticator.",
      "properties": {
        "conditions": {
          "description": "Represents the observations of the authenticator's current state.",
          "items": {
            "description": "Condition contains details for one aspect of the current state of this API Resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
                "maxLength": 32768,
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
                "format": "int64",
                "minimum": 0,
                "type": "integer"
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ],
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "maxLength": 316,
                "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        },
        "phase": {
          "default": "Pending",
          "description": "Phase summarizes the overall status of the JWTAuthenticator.",
          "enum": [
            "Pending",
            "Ready",
            "Error"
          ],
          "type": "string"
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}
