{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "redirect_uris": {
      "minItems": 1,
      "maxItems": 16,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 2048,
        "pattern": "(?:^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S]))|(?:^http:\\/\\/(?:127\\.0\\.0\\.1|\\[::1\\]|localhost)(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S]))"
      }
    },
    "token_endpoint_auth_method": {
      "type": "string",
      "enum": [
        "none",
        "private_key_jwt"
      ]
    },
    "grant_types": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "authorization_code",
          "refresh_token",
          "client_credentials",
          "urn:ietf:params:oauth:grant-type:token-exchange",
          "urn:autonym:params:oauth:grant-type:grant-offer"
        ]
      }
    },
    "response_types": {
      "maxItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "const": "code"
      }
    },
    "client_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[^\\u034f\\u17b4\\u17b5\\u180b-\\u180f\\ufe00-\\ufe0f\\x00-\\x1f\\x7f-\\x9f\\xad\\u061c\\u115f\\u1160\\u200b-\\u200f\\u2028-\\u202e\\u2060-\\u206f\\u3164\\ufeff\\uffa0\\ufff0-\\ufffb\\ud800-\\udfff]+(?![\\s\\S])",
      "description": "Display text: no control, bidirectional formatting, default-ignorable or interlinear annotation character, no line or paragraph separator, and no character outside the Basic Multilingual Plane (above U+FFFF), which a validator reading this pattern by code point rather than by UTF-16 code unit must refuse separately."
    },
    "client_uri": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S])"
    },
    "logo_uri": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S])"
    },
    "tos_uri": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S])"
    },
    "policy_uri": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S])"
    },
    "scope": {
      "type": "string",
      "maxLength": 16384,
      "pattern": "^[\\x21\\x23-\\x5b\\x5d-\\x7e]+(?: [\\x21\\x23-\\x5b\\x5d-\\x7e]+)*(?![\\s\\S])"
    },
    "contacts": {
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 320,
        "pattern": "^[^\\u034f\\u17b4\\u17b5\\u180b-\\u180f\\ufe00-\\ufe0f\\x00-\\x1f\\x7f-\\x9f\\xad\\u061c\\u115f\\u1160\\u200b-\\u200f\\u2028-\\u202e\\u2060-\\u206f\\u3164\\ufeff\\uffa0\\ufff0-\\ufffb\\ud800-\\udfff]+(?![\\s\\S])",
        "description": "Display text: no control, bidirectional formatting, default-ignorable or interlinear annotation character, no line or paragraph separator, and no character outside the Basic Multilingual Plane (above U+FFFF), which a validator reading this pattern by code point rather than by UTF-16 code unit must refuse separately."
      }
    },
    "jwks": {
      "type": "object",
      "properties": {
        "keys": {
          "minItems": 1,
          "maxItems": 100,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "kty": {
                "type": "string",
                "const": "EC"
              },
              "crv": {
                "type": "string",
                "const": "P-256"
              },
              "x": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$"
              },
              "y": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$"
              },
              "kid": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$"
              },
              "alg": {
                "type": "string",
                "const": "ES256"
              },
              "use": {
                "type": "string",
                "const": "sig"
              },
              "exp": {
                "type": "integer",
                "minimum": 1,
                "maximum": 253402300799
              }
            },
            "required": [
              "kty",
              "crv",
              "x",
              "y",
              "kid",
              "alg",
              "use"
            ],
            "additionalProperties": false
          }
        }
      },
      "required": [
        "keys"
      ],
      "additionalProperties": false
    },
    "software_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "pattern": "^[^\\u034f\\u17b4\\u17b5\\u180b-\\u180f\\ufe00-\\ufe0f\\x00-\\x1f\\x7f-\\x9f\\xad\\u061c\\u115f\\u1160\\u200b-\\u200f\\u2028-\\u202e\\u2060-\\u206f\\u3164\\ufeff\\uffa0\\ufff0-\\ufffb\\ud800-\\udfff]+(?![\\s\\S])",
      "description": "Display text: no control, bidirectional formatting, default-ignorable or interlinear annotation character, no line or paragraph separator, and no character outside the Basic Multilingual Plane (above U+FFFF), which a validator reading this pattern by code point rather than by UTF-16 code unit must refuse separately."
    },
    "software_version": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "pattern": "^[^\\u034f\\u17b4\\u17b5\\u180b-\\u180f\\ufe00-\\ufe0f\\x00-\\x1f\\x7f-\\x9f\\xad\\u061c\\u115f\\u1160\\u200b-\\u200f\\u2028-\\u202e\\u2060-\\u206f\\u3164\\ufeff\\uffa0\\ufff0-\\ufffb\\ud800-\\udfff]+(?![\\s\\S])",
      "description": "Display text: no control, bidirectional formatting, default-ignorable or interlinear annotation character, no line or paragraph separator, and no character outside the Basic Multilingual Plane (above U+FFFF), which a validator reading this pattern by code point rather than by UTF-16 code unit must refuse separately."
    },
    "dpop_bound_access_tokens": {
      "type": "boolean",
      "const": true
    },
    "autonym_purge_uri": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https:\\/\\/[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}))?(?:[/?][\\x21\\x22\\x24-\\x5b\\x5d-\\x7e]*)?(?![\\s\\S])"
    }
  },
  "required": [
    "token_endpoint_auth_method"
  ],
  "additionalProperties": false,
  "description": "Client metadata a provider accepts at its RFC 7591 registration endpoint (A6.1). Any other member is refused: jwks_uri, sector_identifier_uri, a software statement and client secrets among them. Omitted grant_types and response_types are authorization_code and code (RFC 7591 section 2). Rules between members, which the schema itself does not state: private_key_jwt needs jwks; client_credentials only with private_key_jwt; urn:autonym:params:oauth:grant-type:grant-offer only with private_key_jwt; refresh_token only with authorization_code; authorization_code goes with the code response type and at least one redirect URI. Redirect URIs, grant types and key IDs are each unique, and each key's kid is its RFC 7638 thumbprint and its coordinates a point on P-256."
}
