{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://stac-extensions.github.io/authentication/v1.2.0/schema.json",
  "title": "Authentication Extension",
  "description": "STAC Authentication Extension for STAC Catalogs, STAC Collections, STAC Items, STAC Assets, and STAC Links.",
  "type": "object",
  "required": [
    "stac_extensions"
  ],
  "properties": {
    "stac_extensions": {
      "type": "array",
      "contains": {
        "const": "https://stac-extensions.github.io/authentication/v1.2.0/schema.json"
      }
    }
  },
  "oneOf": [
    {
      "$comment": "This is the schema for STAC Items.",
      "type": "object",
      "required": [
        "type",
        "properties"
      ],
      "properties": {
        "type": {
          "const": "Feature"
        },
        "properties": {
          "$ref": "#/definitions/schemes_field"
        },
        "assets": {
          "$ref": "#/definitions/assets"
        },
        "links": {
          "$ref": "#/definitions/links"
        }
      }
    },
    {
      "$comment": "This is the schema for STAC Collections",
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "Collection"
        },
        "assets": {
          "$ref": "#/definitions/assets"
        },
        "item_assets": {
          "$ref": "#/definitions/assets"
        },
        "links": {
          "$ref": "#/definitions/links"
        }
      },
      "allOf": [
        {
          "$ref": "#/definitions/schemes_field"
        }
      ]
    },
    {
      "$comment": "This is the schema for STAC Catalogs",
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "Catalog"
        },
        "links": {
          "$ref": "#/definitions/links"
        }
      },
      "allOf": [
        {
          "$ref": "#/definitions/schemes_field"
        }
      ]
    }
  ],
  "definitions": {
    "schemes_field": {
      "type": "object",
      "required": [
        "auth:schemes"
      ],
      "properties": {
        "auth:schemes": {
          "type": "object",
          "patternProperties": {
            "^.*$": {
              "$ref": "#/definitions/auth_scheme"
            }
          },
          "additionalProperties": false
        }
      },
      "patternProperties": {
        "^(?!auth:)": {}
      },
      "additionalProperties": false
    },
    "refs_field": {
      "type": "object",
      "properties": {
        "auth:refs": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "patternProperties": {
        "^(?!auth:)": {}
      },
      "additionalProperties": false
    },
    "assets": {
      "type": "object",
      "additionalProperties": {
        "allOf": [
          {
            "$ref": "#/definitions/refs_field"
          },
          {
            "type": "object",
            "properties": {
              "alternate": {
                "$ref": "#/definitions/refs_field"
              }
            }
          }
        ]
      }
    },
    "links": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/refs_field"
      }
    },
    "auth_scheme": {
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "title": "Scheme keyword",
          "type": "string",
          "examples": [
            "http",
            "s3",
            "signedUrl",
            "oauth2",
            "apiKey",
            "openIdConnect"
          ]
        },
        "description": {
          "title": "Authentication scheme description",
          "type": "string"
        },
        "auth:refs": {
          "title": "Keys of schemes in auth:schemes that may supply this scheme's input (any one of them is completed first; its result is this scheme's input, e.g. the subject_token of a tokenExchange flow)",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "const": "apiKey"
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "name",
              "in"
            ],
            "properties": {
              "name": {
                "title": "API Key header, query, or cookie parameter name",
                "type": "string",
                "examples": [
                  "x-api-key"
                ]
              },
              "in": {
                "title": "Location of the API Key",
                "type": "string",
                "examples": [
                  "query",
                  "header",
                  "cookie"
                ]
              }
            }
          },
          "else": {
            "type": "object",
            "properties": {
              "name": false,
              "in": false
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "const": "http"
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "scheme"
            ],
            "properties": {
              "scheme": {
                "title": "Name of the http authentication scheme",
                "type": "string",
                "examples": [
                  "basic",
                  "bearer",
                  "digest",
                  "dpop",
                  "hoba",
                  "mutual",
                  "negotiate",
                  "oauth",
                  "privatetoken",
                  "scram-sha-1",
                  "scram-sha-256",
                  "vapid"
                ]
              }
            }
          },
          "else": {
            "type": "object",
            "properties": {
              "scheme": false
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "oauth2",
                  "signedUrl"
                ]
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "flows"
            ],
            "if": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "oauth2"
                }
              }
            },
            "then": {
              "type": "object",
              "title": "OAuth2 Flows",
              "properties": {
                "flows": {
                  "additionalProperties": {
                    "$ref": "#/definitions/oauth2_flow"
                  },
                  "allOf": [
                    {
                      "patternProperties": {
                        "^(implicit|authorizationCode)$": {
                          "required": [
                            "authorizationUrl"
                          ]
                        },
                        "^(password|clientCredentials|authorizationCode|tokenExchange)$": {
                          "required": [
                            "tokenUrl"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            },
            "else": {
              "type": "object",
              "title": "Signed URL",
              "properties": {
                "flows": {
                  "additionalProperties": {
                    "$ref": "#/definitions/signed_url_flow"
                  }
                }
              }
            }
          },
          "else": {
            "type": "object",
            "properties": {
              "flows": false
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "const": "openIdConnect"
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "openIdConnectUrl"
            ],
            "properties": {
              "openIdConnectUrl": {
                "title": "This URL returns a JSON listing of the OpenID/OAuth endpoints, supported scopes and claims, public keys used to sign the tokens, and other details",
                "type": "string"
              }
            }
          },
          "else": {
            "type": "object",
            "properties": {
              "openIdConnectUrl": false
            }
          }
        },
        {
          "$comment": "A tokenExchange flow consumes another scheme's token: the scheme must reference at least one scheme; the token obtained through whichever one the client uses is the RFC 8693 subject_token.",
          "if": {
            "type": "object",
            "required": [
              "flows"
            ],
            "properties": {
              "type": {
                "const": "oauth2"
              },
              "flows": {
                "type": "object",
                "required": [
                  "tokenExchange"
                ]
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "auth:refs"
            ],
            "properties": {
              "auth:refs": {
                "type": "array",
                "minItems": 1
              }
            }
          }
        }
      ]
    },
    "oauth2_flow": {
      "type": "object",
      "required": [
        "scopes"
      ],
      "properties": {
        "authorizationUrl": {
          "title": "The authorization URL to be used",
          "type": "string",
          "format": "uri"
        },
        "tokenUrl": {
          "title": "The token URL to be used",
          "type": "string",
          "format": "uri"
        },
        "subjectTokenType": {
          "title": "RFC 8693 subject_token_type URN of the token presented at the tokenUrl (tokenExchange flow)",
          "type": "string",
          "format": "uri",
          "examples": [
            "urn:ietf:params:oauth:token-type:id_token",
            "urn:ietf:params:oauth:token-type:access_token"
          ]
        },
        "refreshUrl": {
          "title": "The URL to be used for obtaining refresh tokens",
          "type": "string",
          "format": "uri"
        },
        "scopes": {
          "title": "The available scopes for the authentication scheme",
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        }
      }
    },
    "signed_url_flow": {
      "type": "object",
      "required": [
        "method",
        "authorizationApi"
      ],
      "properties": {
        "authorizationApi": {
          "title": "The signed URL API endpoint to be used",
          "type": "string",
          "format": "uri"
        },
        "method": {
          "title": "HTTP request method",
          "type": "string",
          "examples": [
            "POST",
            "GET"
          ]
        },
        "responseField": {
          "title": "Key name for the signed URL field in an authorizationApi response",
          "type": "string"
        },
        "parameters": {
          "title": "Parameter definitions for requests to the authorizationApi",
          "additionalProperties": {
            "type": "object",
            "required": [
              "in",
              "required"
            ],
            "properties": {
              "in": {
                "title": "Location of the parameter",
                "type": "string",
                "examples": [
                  "query",
                  "header",
                  "body"
                ]
              },
              "required": {
                "title": "Setting for optional or required parameter",
                "type": "boolean"
              },
              "description": {
                "title": "Plain language description of the parameter",
                "type": "string"
              },
              "schema": {
                "$ref": "http://json-schema.org/draft-07/schema"
              }
            }
          }
        }
      }
    }
  }
}
