{
  "description": "FederationDomain describes the configuration of an OIDC provider.",
  "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 of the OIDC provider.",
      "properties": {
        "identityProviders": {
          "description": "IdentityProviders is the list of identity providers available for use by this FederationDomain.\n\n\nAn identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server,\nhow to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to\nextract a normalized user identity. Normalized user identities include a username and a list of group names.\nIn contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which\nbelong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations\non that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid\naccidental conflicts when multiple identity providers have different users with the same username (e.g.\n\"idp1:ryan\" versus \"idp2:ryan\"). Each entry in IdentityProviders can also implement arbitrary authentication\nrejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow\nthe authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could\ndisallow the authentication unless the user belongs to a specific group in the identity provider.\n\n\nFor backwards compatibility with versions of Pinniped which predate support for multiple identity providers,\nan empty IdentityProviders list will cause the FederationDomain to use all available identity providers which\nexist in the same namespace, but also to reject all authentication requests when there is more than one identity\nprovider currently defined. In this backwards compatibility mode, the name of the identity provider resource\n(e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this\nFederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of\nrelying on this backwards compatibility mode, please consider this mode to be deprecated and please instead\nexplicitly list the identity provider using this IdentityProviders field.",
          "items": {
            "description": "FederationDomainIdentityProvider describes how an identity provider is made available in this FederationDomain.",
            "properties": {
              "displayName": {
                "description": "DisplayName is the name of this identity provider as it will appear to clients. This name ends up in the\nkubeconfig of end users, so changing the name of an identity provider that is in use by end users will be a\ndisruptive change for those users.",
                "minLength": 1,
                "type": "string"
              },
              "objectRef": {
                "description": "ObjectRef is a reference to a Pinniped identity provider resource. A valid reference is required.\nIf the reference cannot be resolved then the identity provider will not be made available.\nMust refer to a resource of one of the Pinniped identity provider types, e.g. OIDCIdentityProvider,\nLDAPIdentityProvider, ActiveDirectoryIdentityProvider.",
                "properties": {
                  "apiGroup": {
                    "description": "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API group.\nFor any other third-party types, APIGroup is required.",
                    "type": "string"
                  },
                  "kind": {
                    "description": "Kind is the type of resource being referenced",
                    "type": "string"
                  },
                  "name": {
                    "description": "Name is the name of resource being referenced",
                    "type": "string"
                  }
                },
                "required": [
                  "kind",
                  "name"
                ],
                "type": "object",
                "x-kubernetes-map-type": "atomic",
                "additionalProperties": false
              },
              "transforms": {
                "description": "Transforms is an optional way to specify transformations to be applied during user authentication and\nsession refresh.",
                "properties": {
                  "constants": {
                    "description": "Constants defines constant variables and their values which will be made available to the transform expressions.",
                    "items": {
                      "description": "FederationDomainTransformsConstant defines a constant variable and its value which will be made available to\nthe transform expressions. This is a union type, and Type is the discriminator field.",
                      "properties": {
                        "name": {
                          "description": "Name determines the name of the constant. It must be a valid identifier name.",
                          "maxLength": 64,
                          "minLength": 1,
                          "pattern": "^[a-zA-Z][_a-zA-Z0-9]*$",
                          "type": "string"
                        },
                        "stringListValue": {
                          "description": "StringListValue should hold the value when Type is \"stringList\", and is otherwise ignored.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "stringValue": {
                          "description": "StringValue should hold the value when Type is \"string\", and is otherwise ignored.",
                          "type": "string"
                        },
                        "type": {
                          "description": "Type determines the type of the constant, and indicates which other field should be non-empty.\nAllowed values are \"string\" or \"stringList\".",
                          "enum": [
                            "string",
                            "stringList"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "name",
                        "type"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array",
                    "x-kubernetes-list-map-keys": [
                      "name"
                    ],
                    "x-kubernetes-list-type": "map"
                  },
                  "examples": {
                    "description": "Examples can optionally be used to ensure that the sequence of transformation expressions are working as\nexpected. Examples define sample input identities which are then run through the expression list, and the\nresults are compared to the expected results. If any example in this list fails, then this\nidentity provider will not be available for use within this FederationDomain, and the error(s) will be\nadded to the FederationDomain status. This can be used to help guard against programming mistakes in the\nexpressions, and also act as living documentation for other administrators to better understand the expressions.",
                    "items": {
                      "description": "FederationDomainTransformsExample defines a transform example.",
                      "properties": {
                        "expects": {
                          "description": "Expects is the expected output of the entire sequence of transforms when they are run against the\ninput Username and Groups.",
                          "properties": {
                            "groups": {
                              "description": "Groups is the expected list of group names after the transformations have been applied.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "message": {
                              "description": "Message is the expected error message of the transforms. When Rejected is true, then Message is the expected\nmessage for the policy which rejected the authentication attempt. When Rejected is true and Message is blank,\nthen Message will be treated as the default error message for authentication attempts which are rejected by a\npolicy. When Rejected is false, then Message is the expected error message for some other non-policy\ntransformation error, such as a runtime error. When Rejected is false, there is no default expected Message.",
                              "type": "string"
                            },
                            "rejected": {
                              "description": "Rejected is a boolean that indicates whether authentication is expected to be rejected by a policy expression\nafter the transformations have been applied. True means that it is expected that the authentication would be\nrejected. The default value of false means that it is expected that the authentication would not be rejected\nby any policy expression.",
                              "type": "boolean"
                            },
                            "username": {
                              "description": "Username is the expected username after the transformations have been applied.",
                              "type": "string"
                            }
                          },
                          "type": "object",
                          "additionalProperties": false
                        },
                        "groups": {
                          "description": "Groups is the input list of group names.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "username": {
                          "description": "Username is the input username.",
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "expects",
                        "username"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array"
                  },
                  "expressions": {
                    "description": "Expressions are an optional list of transforms and policies to be executed in the order given during every\nauthentication attempt, including during every session refresh.\nEach is a CEL expression. It may use the basic CEL language as defined in\nhttps://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in\nhttps://github.com/google/cel-go/tree/master/ext#strings.\n\n\nThe username and groups extracted from the identity provider, and the constants defined in this CR, are\navailable as variables in all expressions. The username is provided via a variable called `username` and\nthe list of group names is provided via a variable called `groups` (which may be an empty list).\nEach user-provided constants is provided via a variable named `strConst.varName` for string constants\nand `strListConst.varName` for string list constants.\n\n\nThe only allowed types for expressions are currently policy/v1, username/v1, and groups/v1.\nEach policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated\nand the authentication attempt is rejected.\nTransformations of type policy/v1 do not return usernames or group names, and therefore cannot change the\nusername or group names.\nEach username/v1 transform must return the new username (a string), which can be the same as the old username.\nTransformations of type username/v1 do not return group names, and therefore cannot change the group names.\nEach groups/v1 transform must return the new groups list (list of strings), which can be the same as the old\ngroups list.\nTransformations of type groups/v1 do not return usernames, and therefore cannot change the usernames.\nAfter each expression, the new (potentially changed) username or groups get passed to the following expression.\n\n\nAny compilation or static type-checking failure of any expression will cause an error status on the FederationDomain.\nDuring an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the\nauthentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username\nand group names have been decided for that authentication attempt.",
                    "items": {
                      "description": "FederationDomainTransformsExpression defines a transform expression.",
                      "properties": {
                        "expression": {
                          "description": "Expression is a CEL expression that will be evaluated based on the Type during an authentication.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "message": {
                          "description": "Message is only used when Type is policy/v1. It defines an error message to be used when the policy rejects\nan authentication attempt. When empty, a default message will be used.",
                          "type": "string"
                        },
                        "type": {
                          "description": "Type determines the type of the expression. It must be one of the supported types.\nAllowed values are \"policy/v1\", \"username/v1\", or \"groups/v1\".",
                          "enum": [
                            "policy/v1",
                            "username/v1",
                            "groups/v1"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "expression",
                        "type"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "type": "array"
                  }
                },
                "type": "object",
                "additionalProperties": false
              }
            },
            "required": [
              "displayName",
              "objectRef"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        },
        "issuer": {
          "description": "Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the\nidentifier that it will use for the iss claim in issued JWTs. This field will also be used as\nthe base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is\nhttps://example.com/foo, then your authorization endpoint will look like\nhttps://example.com/foo/some/path/to/auth/endpoint).\n\n\nSee\nhttps://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.",
          "minLength": 1,
          "type": "string"
        },
        "tls": {
          "description": "TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.",
          "properties": {
            "secretName": {
              "description": "SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains\nthe TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret\nnamed here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use\nfor TLS.\n\n\nServer Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.\n\n\nSecretName is required if you would like to use different TLS certificates for issuers of different hostnames.\nSNI requests do not include port numbers, so all issuers with the same DNS hostname must use the same\nSecretName value even if they have different port numbers.\n\n\nSecretName is not required when you would like to use only the HTTP endpoints (e.g. when the HTTP listener is\nconfigured to listen on loopback interfaces or UNIX domain sockets for traffic from a service mesh sidecar).\nIt is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to\nuse the default TLS certificate, which is configured elsewhere.\n\n\nWhen your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.",
              "type": "string"
            }
          },
          "type": "object",
          "additionalProperties": false
        }
      },
      "required": [
        "issuer"
      ],
      "type": "object",
      "additionalProperties": false
    },
    "status": {
      "description": "Status of the OIDC provider.",
      "properties": {
        "conditions": {
          "description": "Conditions represent the observations of an FederationDomain's current state.",
          "items": {
            "description": "Condition contains details for one aspect of the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path .status.conditions.  For example,\n\n\n\ttype FooStatus struct{\n\t    // Represents the observations of a foo's current state.\n\t    // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n\t    // +patchMergeKey=type\n\t    // +patchStrategy=merge\n\t    // +listType=map\n\t    // +listMapKey=type\n\t    Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t    // other fields\n\t}",
            "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.\n---\nMany .condition.type values are consistent across resources like Available, but because arbitrary conditions can be\nuseful (see .node.status.conditions), the ability to deconflict is important.\nThe regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)",
                "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 FederationDomain.",
          "enum": [
            "Pending",
            "Ready",
            "Error"
          ],
          "type": "string"
        },
        "secrets": {
          "description": "Secrets contains information about this OIDC Provider's secrets.",
          "properties": {
            "jwks": {
              "description": "JWKS holds the name of the corev1.Secret in which this OIDC Provider's signing/verification keys are\nstored. If it is empty, then the signing/verification keys are either unknown or they don't\nexist.",
              "properties": {
                "name": {
                  "default": "",
                  "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.",
                  "type": "string"
                }
              },
              "type": "object",
              "x-kubernetes-map-type": "atomic",
              "additionalProperties": false
            },
            "stateEncryptionKey": {
              "description": "StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for\nencrypting state parameters is stored.",
              "properties": {
                "name": {
                  "default": "",
                  "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.",
                  "type": "string"
                }
              },
              "type": "object",
              "x-kubernetes-map-type": "atomic",
              "additionalProperties": false
            },
            "stateSigningKey": {
              "description": "StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for\nsigning state parameters is stored.",
              "properties": {
                "name": {
                  "default": "",
                  "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.",
                  "type": "string"
                }
              },
              "type": "object",
              "x-kubernetes-map-type": "atomic",
              "additionalProperties": false
            },
            "tokenSigningKey": {
              "description": "TokenSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for\nsigning tokens is stored.",
              "properties": {
                "name": {
                  "default": "",
                  "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.",
                  "type": "string"
                }
              },
              "type": "object",
              "x-kubernetes-map-type": "atomic",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}
