{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://caipe.cisco.com/schemas/102/realm-config-extras.schema.json",
  "title": "Keycloak Realm Config Extras",
  "description": "Sibling to deploy/keycloak/realm-config.json. Carries data the Keycloak importer doesn't itself consume but that the TS and Python middlewares need: per-resource PDP-unavailable fallback rules. Resolution of spec Open Question 1. Resources NOT listed here get implicit 'deny_all' behaviour when the PDP is unreachable.",
  "$comment": "Spec 102 contract. Peers: rbac-matrix.schema.json (matrix routes MAY trigger fallback evaluation when PDP is unreachable), audit-event.schema.json (fallback decisions surface with reason='OK_ROLE_FALLBACK' or 'DENY_PDP_UNAVAILABLE'), python-rbac-helper.md (Python helper consumes this file via realm_extras.get_fallback_rule). Validator: scripts/validate-realm-config.py.",
  "type": "object",
  "required": ["version", "pdp_unavailable_fallback"],
  "additionalProperties": false,
  "properties": {
    "version": {
      "const": 1,
      "description": "Schema version."
    },
    "pdp_unavailable_fallback": {
      "type": "object",
      "description": "Map of Keycloak resource name -> fallback rule. Keys MUST match a resource defined in realm-config.json (cross-validated by scripts/validate-realm-config.py).",
      "patternProperties": {
        "^[a-z0-9_]+$": { "$ref": "#/$defs/FallbackRule" }
      },
      "additionalProperties": false
    }
  },
  "$defs": {
    "FallbackRule": {
      "oneOf": [
        {
          "type": "object",
          "required": ["mode"],
          "additionalProperties": false,
          "properties": {
            "mode": {
              "const": "deny_all",
              "description": "Reject all requests when the PDP is unreachable. The default for resources not listed in this file."
            }
          }
        },
        {
          "type": "object",
          "required": ["mode", "role"],
          "additionalProperties": false,
          "properties": {
            "mode": {
              "const": "realm_role",
              "description": "Allow the request if the bearer's realm_access.roles claim contains the named role; otherwise deny."
            },
            "role": {
              "type": "string",
              "minLength": 1,
              "description": "Realm role name. MUST exist in realm-config.json."
            }
          }
        }
      ]
    }
  },
  "examples": [
    {
      "version": 1,
      "pdp_unavailable_fallback": {
        "admin_ui": {
          "mode": "realm_role",
          "role": "admin"
        },
        "rag": {
          "mode": "deny_all"
        },
        "dynamic_agent": {
          "mode": "deny_all"
        }
      }
    }
  ]
}
