{
  "description": "The Kanidm OAuth2 client custom resource definition (CRD) defines an OAuth2 client\n    integration in Kanidm.",
  "properties": {
    "spec": {
      "additionalProperties": false,
      "description": "The KanidmOAuth2Client custom resource definition (CRD) defines an OAuth2 client integration in\nKanidm. This resource allows you to configure OAuth2 clients that can interact with the Kanidm\nauthorization server. The CRD supports various configurations, including scope maps,\nclaim maps, and other OAuth2 client settings.\nMore info:\nhttps://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status",
      "properties": {
        "allowInsecureClientDisablePkce": {
          "description": "Disable PKCE on this oauth2 client to work around insecure clients that may not support it.\nYou should request the client to enable PKCE!\n\nPublic clients cannot disable PKCE.\nPKCE is enabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "allowLocalhostRedirect": {
          "description": "Allow public clients to redirect to localhost.\n\nJust public clients can allow localhost redirect.\nDisabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "claimMap": {
          "description": "Mapping from a group to a custom claims that it provides to members.",
          "items": {
            "additionalProperties": false,
            "description": "Some OAuth2 services may consume custom claims from an id token for access control or other\npolicy decisions. Each custom claim is a key:values set, where there can be many values\nassociated to a claim name. Different applications may expect these values to be formatted\n(joined) in different ways.\n\nClaim values are mapped based on membership to groups. When an account is a member of multiple\ngroups that would receive the same claim, the values of these maps are merged.",
            "properties": {
              "joinStrategy": {
                "default": "array",
                "description": "The strategy to join the values together.\nPossible strategies to join the values of a claim map:\n`csv` -\u003e \"value_a,value_b\"\n`ssv` -\u003e \"value_a value_b\"\n`array` -\u003e [\"value_a\", \"value_b\"]",
                "enum": [
                  "csv",
                  "ssv",
                  "array"
                ],
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "description": "The name of the claim that will be provided to the client.",
                "type": "string"
              },
              "valuesMap": {
                "items": {
                  "additionalProperties": false,
                  "properties": {
                    "group": {
                      "description": "The group name or SPN that will provide the claim.",
                      "type": "string"
                    },
                    "values": {
                      "description": "The values that will be provided to the client.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "group",
                    "values"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "name",
              "valuesMap"
            ],
            "type": "object"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "disableConsentPrompt": {
          "description": "Disable the consent prompt for this OAuth2 client. This allows skipping the user\nconsent screen for well-known admin-managed applications. When enabled, users will\nnot be prompted to grant consent when authorizing with this client.\n\nDisabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "displayname": {
          "description": "Set the display name for the OAuth2 client.",
          "type": "string"
        },
        "image": {
          "additionalProperties": false,
          "description": "Optional URL to an image for the OAuth2 client application.\nThe image will be downloaded and set in Kanidm for display in the application portal.\nConstraints:\n- Maximum size: 256 KB\n- Maximum dimensions: 1024 x 1024 pixels\n- Supported formats: png, jpg, gif, svg, webp",
          "nullable": true,
          "properties": {
            "url": {
              "description": "URL to fetch the image from (HTTP/HTTPS only).\nThe operator will periodically check this URL for changes using HEAD requests\nand re-download the image when changes are detected.",
              "type": "string"
            }
          },
          "required": [
            "url"
          ],
          "type": [
            "object",
            "null"
          ]
        },
        "jwtLegacyCryptoEnable": {
          "description": "Enable legacy signing crypto on this oauth2 client. This defaults to being disabled.\nYou only need to enable this for openid clients that do not support modern cryptographic\noperations.\n\nDisabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "kanidmName": {
          "description": "The name of the entity in Kanidm. If not specified, the Kubernetes resource name is used.\nUse this field to manage Kanidm entities with names that don't conform to Kubernetes naming rules\n(e.g., entities with underscores like `idm_admin` or `idm_all_persons`).\nThis field is immutable and cannot be changed after creation.",
          "nullable": true,
          "type": [
            "string",
            "null"
          ],
          "x-kubernetes-validations": [
            {
              "message": "kanidmName cannot be changed.",
              "rule": "self == oldSelf"
            }
          ]
        },
        "kanidmRef": {
          "additionalProperties": false,
          "description": "KanidmRef is a reference to a Kanidm object in the same cluster. It is used to specify where\nthe object is stored.",
          "properties": {
            "name": {
              "type": "string"
            },
            "namespace": {
              "description": "For cross-namespace resources. Reference Kanidm namespace. If omitted, the namespace of the\nresource will be used.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "name"
          ],
          "type": "object",
          "x-kubernetes-validations": [
            {
              "message": "Value is immutable",
              "rule": "self == oldSelf"
            }
          ]
        },
        "origin": {
          "description": "Set the landing page (home page) of the client. The landing page is where users will be\nredirected to from the Kanidm application portal.",
          "type": "string"
        },
        "preferShortUsername": {
          "description": "Use the 'name' attribute instead of 'spn' for the preferred_username.\n\nDisabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "public": {
          "default": false,
          "description": "Create a new OAuth2 public client that requires PKCE. You should prefer using confidential\nclient types if possible over public ones.\n\nPublic clients have many limitations and can not access all API's of OAuth2. For example\nrfc7662 token introspection requires client authentication.\n\nThis cannot be changed after creation. Default value is false.\nThis field is immutable.\nIf public is false, the operator will create a secret containing the client secret with\nthe name `\u003coauth2-client-name\u003e-kanidm-oauth2-credentials` in the same namespace as the OAuth2 client.",
          "type": [
            "boolean",
            "null"
          ],
          "x-kubernetes-validations": [
            {
              "message": "Public cannot be changed.",
              "rule": "self == oldSelf"
            }
          ]
        },
        "redirectUrl": {
          "description": "Set the URL where the application expects OAuth2 requests to be sent.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "scopeMap": {
          "description": "Main scope map for the OAuth2 client. For an authorization to proceed, all scopes requested\nby the client must be available in the final scope set that is granted to the account.",
          "items": {
            "additionalProperties": false,
            "description": "The `KanidmScopeMap` struct represents a mapping of a group to a set of OAuth2 scopes in Kanidm.\n\nScope maps in Kanidm are used to define the permissions that a client application can request on\nbehalf of a user. These scopes determine what resources the client can access and what\noperations it can perform.\n\nThese provide a set of scopes if a user is a member of a specific group within Kanidm. This\nallows you to create a relationship between the scopes of a service, and the groups/roles in\nKanidm which can be specific to that service.",
            "properties": {
              "group": {
                "description": "Group name or SPN. Members of this group will be granted the scopes defined in the `scopes` field.",
                "type": "string"
              },
              "scopes": {
                "description": "A scope is a string that represents a specific permission or set of permissions that a\nclient application can request from an authorization server. Scopes define the level of\naccess that the client application is granted to the user's resources.\n\nOpenID Connect allows a number of scopes that affect the content of the resulting authorization\ntoken. If one of the following scopes is requested by the OpenID client, then the associated\nclaims may be added to the authorization token. It is not guaranteed that all of the associated\nclaims will be added.\n\n- `profile`: name, family_name, given_name, middle_name, nickname, preferred_username, profile,\n   picture, website, gender, birthdate, zoneinfo, locale, and updated_at\n- `email`: email, email_verified\n- `address`: address\n- `phone`: phone_number, phone_number_verified\n- `groups`: groups\n\nIf you are creating an OpenID Connect (OIDC) client, you MUST provide a scope map containing `openid`.\nWithout this, OpenID Connect clients WILL NOT WORK!",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "group",
              "scopes"
            ],
            "type": "object"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "secretKeyAliases": {
          "additionalProperties": false,
          "description": "Aliases for the canonical secret keys (CLIENT_ID and CLIENT_SECRET).\nAllows consumers that require different fixed key names to access the same credentials.\nThe canonical keys CLIENT_ID and CLIENT_SECRET are always present.\nOnly applies to confidential clients (public: false).",
          "nullable": true,
          "properties": {
            "clientId": {
              "description": "Aliases for the CLIENT_ID key.\nEach alias will be added as an additional key containing the same client ID value.",
              "items": {
                "type": "string"
              },
              "nullable": true,
              "type": [
                "array",
                "null"
              ]
            },
            "clientSecret": {
              "description": "Aliases for the CLIENT_SECRET key.\nEach alias will be added as an additional key containing the same client secret value.",
              "items": {
                "type": "string"
              },
              "nullable": true,
              "type": [
                "array",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "secretRotation": {
          "additionalProperties": false,
          "description": "Automatic rotation configuration for the OAuth2 client secret. Only applies to confidential\nclients (public: false). When enabled, the operator will regenerate the client secret\nperiodically based on the configured rotation period.",
          "nullable": true,
          "properties": {
            "enabled": {
              "default": false,
              "description": "Enable automatic secret rotation. Defaults to false (opt-in).",
              "type": [
                "boolean",
                "null"
              ]
            },
            "periodDays": {
              "default": 90,
              "description": "Rotation period in days. Secrets will be rotated when they are older than this period.\nDefaults to 90 days.",
              "format": "uint32",
              "minimum": 0,
              "type": [
                "integer",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "secretTemplate": {
          "additionalProperties": false,
          "description": "Template applied to the Secret created for confidential clients (public: false).\nAllows attaching custom annotations and labels to the generated Secret. The operator's own\nlabels and annotations take precedence over any conflicting keys in the template.\nChanges to this template are enforced on the next reconciliation, overwriting any manual\nmodifications made to the Secret",
          "nullable": true,
          "properties": {
            "annotations": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Annotations to add to the object. The operator's own annotations take precedence over\nany keys specified here.",
              "nullable": true,
              "type": [
                "object",
                "null"
              ]
            },
            "labels": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Labels to add to the object. The operator's own labels take precedence over any keys\nspecified here.",
              "nullable": true,
              "type": [
                "object",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        },
        "strictRedirectUrl": {
          "description": "Enable strict validation of redirect URLs. Previously redirect URLs only validated the\norigin of the URL matched. When enabled, redirect URLs must match exactly.\n\nEnabled by default.",
          "nullable": true,
          "type": [
            "boolean",
            "null"
          ]
        },
        "supScopeMap": {
          "description": "Supplementary scope maps for the OAuth2 client. These function the same as scope maps where\nmembership of a group provides a set of scopes to the account.\nHowever these scopes are NOT consulted during authorization decisions made by Kanidm.\nThese scopes exist to allow optional properties to be provided (such as personal\ninformation about a subset of accounts to be revealed) or so that the service may make its\nown authorization decisions based on the provided scopes.",
          "items": {
            "additionalProperties": false,
            "description": "The `KanidmScopeMap` struct represents a mapping of a group to a set of OAuth2 scopes in Kanidm.\n\nScope maps in Kanidm are used to define the permissions that a client application can request on\nbehalf of a user. These scopes determine what resources the client can access and what\noperations it can perform.\n\nThese provide a set of scopes if a user is a member of a specific group within Kanidm. This\nallows you to create a relationship between the scopes of a service, and the groups/roles in\nKanidm which can be specific to that service.",
            "properties": {
              "group": {
                "description": "Group name or SPN. Members of this group will be granted the scopes defined in the `scopes` field.",
                "type": "string"
              },
              "scopes": {
                "description": "A scope is a string that represents a specific permission or set of permissions that a\nclient application can request from an authorization server. Scopes define the level of\naccess that the client application is granted to the user's resources.\n\nOpenID Connect allows a number of scopes that affect the content of the resulting authorization\ntoken. If one of the following scopes is requested by the OpenID client, then the associated\nclaims may be added to the authorization token. It is not guaranteed that all of the associated\nclaims will be added.\n\n- `profile`: name, family_name, given_name, middle_name, nickname, preferred_username, profile,\n   picture, website, gender, birthdate, zoneinfo, locale, and updated_at\n- `email`: email, email_verified\n- `address`: address\n- `phone`: phone_number, phone_number_verified\n- `groups`: groups\n\nIf you are creating an OpenID Connect (OIDC) client, you MUST provide a scope map containing `openid`.\nWithout this, OpenID Connect clients WILL NOT WORK!",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "group",
              "scopes"
            ],
            "type": "object"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        }
      },
      "required": [
        "displayname",
        "kanidmRef",
        "origin",
        "redirectUrl"
      ],
      "type": "object"
    },
    "status": {
      "additionalProperties": false,
      "description": "Most recent observed status of the Kanidm Group. Read-only.\nMore info:\nhttps://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status",
      "nullable": true,
      "properties": {
        "claimsMap": {
          "items": {
            "type": "string"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "conditions": {
          "items": {
            "additionalProperties": false,
            "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. This 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. This may be an empty string.",
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "image": {
          "additionalProperties": false,
          "description": "Status of the OAuth2 client image.",
          "nullable": true,
          "properties": {
            "contentHash": {
              "description": "Hash of the image content (SHA-256, for validation).",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "contentLength": {
              "description": "Content-Length from the last fetch.",
              "format": "uint64",
              "minimum": 0,
              "nullable": true,
              "type": [
                "integer",
                "null"
              ]
            },
            "etag": {
              "description": "ETag header from the last fetch (for change detection).",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "lastModified": {
              "description": "Last-Modified header from the last fetch.",
              "nullable": true,
              "type": [
                "string",
                "null"
              ]
            },
            "url": {
              "description": "The URL from which the image was last fetched.",
              "type": "string"
            }
          },
          "required": [
            "url"
          ],
          "type": [
            "object",
            "null"
          ]
        },
        "kanidmRef": {
          "type": "string"
        },
        "origin": {
          "items": {
            "type": "string"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "ready": {
          "type": "boolean"
        },
        "scopeMap": {
          "items": {
            "type": "string"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        },
        "secretName": {
          "nullable": true,
          "type": [
            "string",
            "null"
          ]
        },
        "supScopeMap": {
          "items": {
            "type": "string"
          },
          "nullable": true,
          "type": [
            "array",
            "null"
          ]
        }
      },
      "required": [
        "kanidmRef",
        "ready"
      ],
      "type": [
        "object",
        "null"
      ]
    }
  },
  "required": [
    "spec"
  ],
  "title": "KanidmOAuth2Client",
  "type": "object"
}