{
  "$id": "https://json.schemastore.org/app-config.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Application Configuration Schema",
  "type": "object",
  "description": "This is the schema describing the structure of the app-config.yaml configuration file.",
  "properties": {
    "app": {
      "type": "object",
      "description": "Generic frontend configuration.",
      "properties": {
        "baseUrl": {
          "type": "string",
          "description": "The public absolute root URL that the frontend."
        },
        "title": {
          "type": "string",
          "description": "The title of the app, as shown in the Backstage web interface."
        },
        "datadogRum": {
          "type": "object",
          "description": "Datadog RUM events configuration",
          "properties": {
            "env": {
              "type": "string",
              "description": "Environment for Datadog RUM events"
            },
            "clientToken": {
              "type": "string",
              "description": "clientToken for Datadog RUM events"
            },
            "applicationId": {
              "type": "string",
              "description": "applicationId for Datadog RUM events"
            },
            "site": {
              "type": "string",
              "description": "site for Datadog RUM events"
            }
          }
        },
        "listen": {
          "type": "object",
          "description": "Listening configuration for local development",
          "properties": {
            "host": {
              "type": "string",
              "description": "The host that the frontend should be bound to. Only used for local development."
            },
            "port": {
              "type": "number",
              "description": "The port that the frontend should be bound to. Only used for local development."
            }
          }
        },
        "https": {
          "type": "object",
          "description": "Only used for local development. The https object is passed to webpack in order to enable using https on localhost.",
          "properties": {
            "certificate": {
              "type": "object",
              "description": "Parent object containing certificate and the private key",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Https Certificate private key. Use $file to load in a file"
                },
                "cert": {
                  "type": "string",
                  "description": "Https Certificate. Use $file to load in a file"
                }
              }
            }
          }
        },
        "support": {
          "description": "Information about support of this Backstage instance and how to contact the integrator team.",
          "type": "object",
          "properties": {
            "url": {
              "description": "The primary support url.",
              "type": "string"
            },
            "items": {
              "description": "A list of categorized support item groupings.",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "title": {
                    "description": "The title of the support item grouping.",
                    "type": "string"
                  },
                  "icon": {
                    "description": "An optional icon for the support item grouping.",
                    "type": "string"
                  },
                  "links": {
                    "description": "A list of support links for the Backstage instance inside this grouping.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "extensions": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "attachTo": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "input": {
                              "type": "string"
                            }
                          }
                        },
                        "disabled": {
                          "type": "boolean"
                        },
                        "config": {}
                      }
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                }
              },
              {
                "type": "string"
              }
            ]
          }
        },
        "analytics": {
          "type": "object",
          "properties": {
            "ga": {
              "type": "object",
              "properties": {
                "trackingId": {
                  "description": "Google Analytics tracking ID, e.g. UA-000000-0",
                  "type": "string"
                },
                "scriptSrc": {
                  "description": "URL to Google Analytics analytics.js script\nDefaults to fetching from GA source (eg. https://www.google-analytics.com/analytics.js)",
                  "type": "string"
                },
                "identity": {
                  "description": "Controls how the identityApi is used when sending data to GA:\n\n- `disabled`: (Default) Explicitly prevents a user's identity from\n  being used when capturing events in GA.\n- `optional`: Pageviews and hits are forwarded to GA as they happen\n  and only include user identity metadata once known. Guarantees\n  that hits are captured for all sessions, even if no sign in\n  occurs, but may result in dropped hits in User ID views.\n- `required`: All pageviews and hits are deferred until an identity\n  is known. Guarantees that all data sent to GA correlates to a user\n  identity, but prevents GA from receiving events for sessions in\n  which a user does not sign in. An `identityApi` instance must be\n  passed during instantiation when set to this value.",
                  "enum": ["disabled", "optional", "required"],
                  "type": "string"
                },
                "virtualSearchPageView": {
                  "description": "Controls whether to send virtual pageviews on `search` events.\nCan be used to enable Site Search in GA.",
                  "type": "object",
                  "properties": {
                    "mode": {
                      "description": "- `disabled`: (Default) no virtual pageviews are sent\n- `only`: Sends virtual pageview _instead_ of the `search` event\n- `both`: Sends both the `search` event _and_ the virtual pageview",
                      "enum": ["both", "disabled", "only"],
                      "type": "string"
                    },
                    "mountPath": {
                      "description": "Specifies on which path the main Search page is mounted.\nDefaults to `/search`.",
                      "type": "string"
                    },
                    "searchQuery": {
                      "description": "Specifies which query param is used for the term query in the virtual pageview URL.\nDefaults to `query`.",
                      "type": "string"
                    },
                    "categoryQuery": {
                      "description": "Specifies which query param is used for the category query in the virtual pageview URL.\nSkipped by default.",
                      "type": "string"
                    }
                  }
                },
                "debug": {
                  "description": "Whether or not to log analytics debug statements to the console.\nDefaults to false.",
                  "type": "boolean"
                },
                "testMode": {
                  "description": "Prevents events from actually being sent when set to true. Defaults\nto false.",
                  "type": "boolean"
                },
                "customDimensionsMetrics": {
                  "description": "Configuration informing how Analytics Context and Event Attributes\nmetadata will be captured in Google Analytics.",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "description": "Specifies whether the corresponding metadata should be collected\nas a Google Analytics custom dimension or custom metric.",
                        "enum": ["dimension", "metric"],
                        "type": "string"
                      },
                      "index": {
                        "description": "The index of the Google Analytics custom dimension or metric that\nthe metadata should be written to.",
                        "type": "number"
                      },
                      "source": {
                        "description": "Specifies whether the desired value lives as an attribute on the\nAnalytics Context or the Event's Attributes.",
                        "enum": ["attributes", "context"],
                        "type": "string"
                      },
                      "key": {
                        "description": "The property of the context or attributes that should be captured.\ne.g. to capture the Plugin ID associated with an event, the source\nshould be set to \"context\" and the key should be set to pluginId.",
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "ga4": {
              "type": "object",
              "properties": {
                "measurementId": {
                  "description": "Google Analytics measurement ID, e.g. G-000000-0",
                  "type": "string"
                },
                "identity": {
                  "description": "Controls how the identityApi is used when sending data to GA:\n\n- `disabled`: (Default) Explicitly prevents a user's identity from\n  being used when capturing events in GA.\n- `optional`: Pageviews and hits are forwarded to GA as they happen\n  and only include user identity metadata once known. Guarantees\n  that hits are captured for all sessions, even if no sign in\n  occurs, but may result in dropped hits in User ID views.\n- `required`: All pageviews and hits are deferred until an identity\n  is known. Guarantees that all data sent to GA correlates to a user\n  identity, but prevents GA from receiving events for sessions in\n  which a user does not sign in. An `identityApi` instance must be\n  passed during instantiation when set to this value.",
                  "enum": ["disabled", "optional", "required"],
                  "type": "string"
                },
                "debug": {
                  "description": "Whether to log analytics debug statements to the console.\nDefaults to false.",
                  "type": "boolean"
                },
                "testMode": {
                  "description": "Prevents events from actually being sent when set to true. Defaults\nto false.",
                  "type": "boolean"
                },
                "contentGrouping": {
                  "description": "Content grouping definition\nFeature available in Google Analytics 4\nMore information https://support.google.com/analytics/answer/11523339?hl=en\nData can be grouped by pluginId, routeRef\nTakes 24 hours before metrics shows up in GA dashboard\nSpecifies the dimension to be used for content grouping\nCan be one of pluginId, extension or routeRef",
                  "enum": ["extension", "pluginId", "routeRef"],
                  "type": "string"
                },
                "allowedContexts": {
                  "description": "Configuration informing how Analytics Context and Event Attributes\nmetadata will be captured in Google Analytics.\nContexts that will be sent as parameters in the event.\ncontext-name will be prefixed by c_, for example, pluginId will be c_pluginId in the event.",
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "array",
                      "items": [
                        {
                          "type": "string",
                          "enum": ["*"]
                        }
                      ],
                      "minItems": 1,
                      "maxItems": 1
                    }
                  ]
                },
                "allowedAttributes": {
                  "description": "Attributes that will be sent as parameters in the event\nattribute-name will be prefixed by a_, for example , testAttribute will be c_testAttribute in the event.",
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "array",
                      "items": [
                        {
                          "type": "string",
                          "enum": ["*"]
                        }
                      ],
                      "minItems": 1,
                      "maxItems": 1
                    }
                  ]
                }
              }
            },
            "newRelic": {
              "type": "object",
              "properties": {
                "endpoint": {
                  "description": "Data ingestion endpoint to use, either bam.eu01.nr-data.net (EU) or bam.nr-data.net (US)",
                  "enum": ["bam.eu01.nr-data.net", "bam.nr-data.net"],
                  "type": "string"
                },
                "accountId": {
                  "description": "New Relic Account ID, e.g. 1234567",
                  "type": "string"
                },
                "applicationId": {
                  "description": "New Relic Application ID, e.g. 987654321",
                  "type": "string"
                },
                "licenseKey": {
                  "description": "New Relic License Key, e.g. NRJS-12a3456bc78de9123f4",
                  "type": "string"
                },
                "distributedTracingEnabled": {
                  "description": "Whether to enabled distributed tracing, defaults to false",
                  "type": "boolean"
                },
                "cookiesEnabled": {
                  "description": "Whether to enabled tracing of cookies, defaults to false",
                  "type": "boolean"
                }
              }
            }
          }
        },
        "packageName": {
          "description": "The name of the app package (in most Backstage repositories, this is the\n\"name\" field in `packages/app/package.json`) that content should be served\nfrom. The same app package should be added as a dependency to the backend\npackage in order for it to be accessible at runtime.\n\nIn a typical setup with a single app package, this will default to 'app'.",
          "type": "string"
        },
        "disableConfigInjection": {
          "description": "Disables the configuration injection. This can be useful if you're running in an environment\nwith a read-only filesystem, or for some other reason don't want configuration to be injected.\n\nNote that this will cause the configuration used when building the app bundle to be used, unless\na separate configuration loading strategy is set up.\n\nThis also disables configuration injection though `APP_CONFIG_` environment variables.",
          "type": "boolean"
        },
        "disableStaticFallbackCache": {
          "description": "By default the app backend plugin will cache previously deployed static assets in the database.\nIf you disable this, it is recommended to set a `staticFallbackHandler` instead.",
          "type": "boolean"
        }
      }
    },
    "allure": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "type": "string"
        }
      }
    },
    "firehydrant": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "type": "string"
        }
      }
    },
    "lighthouse": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "type": "string"
        }
      }
    },
    "nomad": {
      "type": "object",
      "properties": {
        "addr": {
          "type": "string",
          "description": "The address of the Nomad API. See: https://developer.hashicorp.com/nomad/api-docs#addressing-and-ports"
        },
        "token": {
          "type": "string",
          "description": "The token to call the Nomad API with. See: https://developer.hashicorp.com/nomad/api-docs#authentication"
        }
      }
    },
    "auth": {
      "type": "object",
      "description": "Configuration that provides information on available configured authentication providers.",
      "properties": {
        "providers": {
          "type": "object",
          "description": "The available auth-provider options and attributes",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": true
          },
          "properties": {
            "google": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  }
                }
              }
            },
            "github": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  },
                  "enterpriseInstanceUrl": {
                    "type": "string"
                  }
                }
              }
            },
            "saml": {
              "type": "object",
              "properties": {
                "entryPoint": {
                  "type": "string"
                },
                "logoutUrl": {
                  "type": "string"
                },
                "issuer": {
                  "type": "string"
                },
                "cert": {
                  "type": "string"
                },
                "audience": {
                  "type": "string"
                },
                "privateKey": {
                  "type": "string"
                },
                "authnContext": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "identifierFormat": {
                  "type": "string"
                },
                "decryptionPvk": {
                  "type": "string"
                },
                "signatureAlgorithm": {
                  "enum": ["sha256", "sha512"],
                  "type": "string"
                },
                "digestAlgorithm": {
                  "type": "string"
                },
                "acceptedClockSkewMs": {
                  "type": "number"
                }
              }
            },
            "okta": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "audience": {
                    "type": "string"
                  },
                  "authServerId": {
                    "type": "string"
                  },
                  "idp": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  }
                }
              }
            },
            "oauth2": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "authorizationUrl": {
                    "type": "string"
                  },
                  "tokenUrl": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  },
                  "disableRefresh": {
                    "type": "boolean"
                  },
                  "includeBasicAuth": {
                    "type": "boolean"
                  }
                }
              }
            },
            "oidc": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  },
                  "metadataUrl": {
                    "type": "string"
                  },
                  "tokenEndpointAuthMethod": {
                    "type": "string"
                  },
                  "tokenSignedResponseAlg": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  },
                  "prompt": {
                    "type": "string"
                  }
                }
              }
            },
            "auth0": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "domain": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  },
                  "audience": {
                    "type": "string"
                  },
                  "connection": {
                    "type": "string"
                  },
                  "connectionScope": {
                    "type": "string"
                  }
                }
              }
            },
            "microsoft": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "tenantId": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  }
                }
              }
            },
            "onelogin": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "issuer": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  }
                }
              }
            },
            "awsalb": {
              "type": "object",
              "properties": {
                "iss": {
                  "type": "string"
                },
                "region": {
                  "type": "string"
                }
              }
            },
            "cfaccess": {
              "type": "object",
              "properties": {
                "teamName": {
                  "type": "string"
                }
              }
            },
            "gcpIap": {
              "description": "Configuration for the Google Cloud Platform Identity-Aware Proxy (IAP) auth provider.",
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "audience": {
                    "description": "The audience to use when validating incoming JWT tokens.\nSee https://backstage.io/docs/auth/google/gcp-iap-auth",
                    "type": "string"
                  },
                  "jwtHeader": {
                    "description": "The name of the header to read the JWT token from, defaults to `'x-goog-iap-jwt-assertion'`.",
                    "type": "string"
                  }
                }
              }
            },
            "gitlab": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "audience": {
                    "type": "string"
                  },
                  "callbackUrl": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "environment": {
          "description": "The 'environment' attribute added as an optional parameter to have configurable environment value for `auth.providers`.\ndefault value: 'development'\noptional values: 'development' | 'production'",
          "type": "string"
        },
        "session": {
          "type": "object",
          "properties": {
            "secret": {
              "description": "The secret attribute of session object.",
              "type": "string"
            }
          }
        },
        "identityTokenAlgorithm": {
          "description": "JWS \"alg\" (Algorithm) Header Parameter value. Defaults to ES256.\nMust match one of the algorithms defined for IdentityClient.\nWhen setting a different algorithm, check if the `key` field\nof the `signing_keys` table can fit the length of the generated keys.\nIf not, add a knex migration file in the migrations folder.\nMore info on supported algorithms: https://github.com/panva/jose",
          "type": "string"
        },
        "keyStore": {
          "description": "To control how to store JWK data in auth-backend",
          "type": "object",
          "properties": {
            "provider": {
              "enum": ["database", "firestore", "memory"],
              "type": "string"
            },
            "firestore": {
              "type": "object",
              "properties": {
                "host": {
                  "description": "The host to connect to",
                  "type": "string"
                },
                "port": {
                  "description": "The port to connect to",
                  "type": "number"
                },
                "ssl": {
                  "description": "Whether to use SSL when connecting.",
                  "type": "boolean"
                },
                "projectId": {
                  "description": "The Google Cloud Project ID",
                  "type": "string"
                },
                "keyFilename": {
                  "description": "Local file containing the Service Account credentials.\nYou can omit this value to automatically read from\nGOOGLE_APPLICATION_CREDENTIALS env which is useful for local\ndevelopment.",
                  "type": "string"
                },
                "path": {
                  "description": "The path to use for the collection. Defaults to 'sessions'",
                  "type": "string"
                },
                "timeout": {
                  "description": "Timeout used for database operations. Defaults to 10000ms",
                  "type": "number"
                }
              }
            }
          }
        }
      }
    },
    "backend": {
      "type": "object",
      "description": "Generic backend configuration.",
      "properties": {
        "auth": {
          "description": "Backend configuration for when request authentication is enabled",
          "type": "object",
          "properties": {
            "keys": {
              "description": "Keys shared by all backends for signing and validating backend tokens.",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "secret": {
                    "description": "Secret for generating tokens. Should be a base64 string, recommended\nlength is 24 bytes.",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "baseUrl": {
          "type": "string",
          "description": "The public absolute root URL that the backend is reachable at, from the browser's perspective."
        },
        "listen": {
          "description": "Address that the backend should listen to.",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "host": {
                  "description": "Address of the interface that the backend should bind to.",
                  "type": "string"
                },
                "port": {
                  "description": "Port that the backend should listen to.",
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ]
                }
              }
            },
            {
              "type": "string"
            }
          ]
        },
        "https": {
          "description": "HTTPS configuration for the backend. If omitted the backend will serve HTTP.\n\nSetting this to `true` will cause self-signed certificates to be generated, which\ncan be useful for local development or other non-production scenarios.",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "certificate": {
                  "description": "Certificate configuration",
                  "type": "object",
                  "properties": {
                    "cert": {
                      "description": "PEM encoded certificate. Use $file to load in a file",
                      "type": "string"
                    },
                    "key": {
                      "description": "PEM encoded certificate key. Use $file to load in a file.",
                      "type": "string"
                    }
                  }
                }
              }
            },
            {
              "enum": [true],
              "type": "boolean"
            }
          ]
        },
        "database": {
          "description": "Database connection configuration, select base database type using the `client` field",
          "type": "object",
          "properties": {
            "client": {
              "description": "Default database client to use",
              "enum": ["better-sqlite3", "pg", "sqlite3"],
              "type": "string"
            },
            "connection": {
              "description": "Base database connection string, or object with individual connection properties",
              "anyOf": [
                {
                  "type": "object",
                  "additionalProperties": {},
                  "properties": {
                    "password": {
                      "description": "Password that belongs to the client User",
                      "type": "string"
                    }
                  }
                },
                {
                  "type": "string"
                }
              ]
            },
            "prefix": {
              "description": "Database name prefix override",
              "type": "string"
            },
            "ensureExists": {
              "description": "Whether to ensure the given database exists by creating it if it does not.\nDefaults to true if unspecified.",
              "type": "boolean"
            },
            "pluginDivisionMode": {
              "description": "How plugins databases are managed/divided in the provided database instance.\n\n`database` -> Plugins are each given their own database to manage their schemas/tables.\n\n`schema` -> Plugins will be given their own schema (in the specified/default database)\n            to manage their tables.\n\nNOTE: Currently only supported by the `pg` client.",
              "default": "database",
              "enum": ["database", "schema"],
              "type": "string"
            },
            "role": {
              "description": "Configures the ownership of newly created schemas in pg databases.",
              "type": "string"
            },
            "knexConfig": {
              "description": "Arbitrary config object to pass to knex when initializing\n(https://knexjs.org/#Installation-client). Most notable is the debug\nand asyncStackTraces booleans",
              "type": "object",
              "additionalProperties": true
            },
            "plugin": {
              "description": "Plugin specific database configuration and client override",
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "client": {
                    "description": "Database client override",
                    "enum": ["better-sqlite3", "pg", "sqlite3"],
                    "type": "string"
                  },
                  "connection": {
                    "description": "Database connection string or Knex object override",
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      },
                      {
                        "type": "string"
                      }
                    ]
                  },
                  "ensureExists": {
                    "description": "Whether to ensure the given database exists by creating it if it does not.\nDefaults to base config if unspecified.",
                    "type": "boolean"
                  },
                  "knexConfig": {
                    "description": "Arbitrary config object to pass to knex when initializing\n(https://knexjs.org/#Installation-client). Most notable is the\ndebug and asyncStackTraces booleans.\n\nThis is merged recursively into the base knexConfig",
                    "type": "object",
                    "additionalProperties": true
                  },
                  "role": {
                    "description": "Configures the ownership of newly created schemas in pg databases.",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "cache": {
          "description": "Cache connection configuration, select cache type using the `store` field",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "store": {
                  "type": "string",
                  "enum": ["memory"]
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "store": {
                  "type": "string",
                  "enum": ["redis"]
                },
                "connection": {
                  "description": "A redis connection string in the form `redis://user:pass@host:port`.",
                  "type": "string"
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "store": {
                  "type": "string",
                  "enum": ["memcache"]
                },
                "connection": {
                  "description": "A memcache connection string in the form `user:pass@host:port`.",
                  "type": "string"
                }
              }
            }
          ]
        },
        "cors": {
          "type": "object",
          "properties": {
            "origin": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "string"
                }
              ]
            },
            "methods": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "string"
                }
              ]
            },
            "allowedHeaders": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "string"
                }
              ]
            },
            "exposedHeaders": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "string"
                }
              ]
            },
            "credentials": {
              "type": "boolean"
            },
            "maxAge": {
              "type": "number"
            },
            "preflightContinue": {
              "type": "boolean"
            },
            "optionsSuccessStatus": {
              "type": "number"
            }
          }
        },
        "reading": {
          "description": "Configuration related to URL reading, used for example for reading catalog info\nfiles, scaffolder templates, and techdocs content.",
          "type": "object",
          "properties": {
            "allow": {
              "description": "A list of targets to allow outgoing requests to. Users will be able to make\nrequests on behalf of the backend to the targets that are allowed by this list.",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "host": {
                    "description": "A host to allow outgoing requests to, being either a full host or\na subdomain wildcard pattern with a leading `*`. For example `example.com`\nand `*.example.com` are valid values, `prod.*.example.com` is not.\nThe host may also contain a port, for example `example.com:8080`.",
                    "type": "string"
                  },
                  "paths": {
                    "description": "An optional list of paths. In case they are present only targets matching\nany of them will are allowed. You can use trailing slashes to make sure only\nsubdirectories are allowed, for example `/mydir/` will allow targets with\npaths like `/mydir/a` but will block paths like `/mydir2`.",
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "csp": {
          "description": "Content Security Policy options.\n\nThe keys are the plain policy ID, e.g. \"upgrade-insecure-requests\". The\nvalues are on the format that the helmet library expects them, as an\narray of strings. There is also the special value false, which means to\nremove the default value that Backstage puts in place for that policy.",
          "type": "object",
          "additionalProperties": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "enum": [false],
                "type": "boolean"
              }
            ]
          }
        }
      }
    },
    "discovery": {
      "description": "Discovery options.",
      "type": "object",
      "properties": {
        "endpoints": {
          "description": "Endpoints\n\nA list of target baseUrls and the associated plugins.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "target": {
                "description": "The target baseUrl to use for the plugin\n\nCan be either a string or an object with internal and external keys.\nTargets with `{{pluginId}}` or `{{ pluginId }} in the url will be replaced with the pluginId.",
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "external": {
                        "type": "string"
                      },
                      "internal": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              "plugins": {
                "description": "Array of plugins which use the target baseUrl.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "organization": {
      "description": "Configuration that provides information about the organization that the app is for.",
      "type": "object",
      "properties": {
        "name": {
          "description": "The name of the organization that the app belongs to.",
          "type": "string"
        }
      }
    },
    "homepage": {
      "description": "This config was used by the HomepageTimer but has been replaced  by the HeaderWorldClock in the home plugin",
      "deprecated": "in favor of the HeaderWorldClock which is found in the home plugin",
      "type": "object",
      "properties": {
        "clocks": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "timezone": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "enableExperimentalRedirectFlow": {
      "description": "Enable redirect authentication flow type, instead of a popup for authentication.",
      "type": "boolean"
    },
    "integrations": {
      "description": "Configuration for integrations towards various external repository provider systems",
      "type": "object",
      "properties": {
        "azure": {
          "description": "Integration configuration for Azure",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given Azure instance",
                "type": "string"
              },
              "token": {
                "description": "Token used to authenticate requests.",
                "deprecated": "Use `credentials` instead.",
                "type": "string"
              },
              "credential": {
                "description": "The credential to use for requests.\n\nIf no credential is specified anonymous access is used.",
                "deprecated": "Use `credentials` instead.",
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string"
                  },
                  "clientSecret": {
                    "type": "string"
                  },
                  "tenantId": {
                    "type": "string"
                  },
                  "personalAccessToken": {
                    "type": "string"
                  }
                }
              },
              "credentials": {
                "description": "The credentials to use for requests. If multiple credentials are specified the first one that matches the organization is used.\nIf not organization matches the first credential without an organization is used.\n\nIf no credentials are specified at all, either a default credential (for Azure DevOps) or anonymous access (for Azure DevOps Server) is used.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "clientId": {
                      "type": "string"
                    },
                    "clientSecret": {
                      "type": "string"
                    },
                    "tenantId": {
                      "type": "string"
                    },
                    "personalAccessToken": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "bitbucket": {
          "description": "Integration configuration for Bitbucket",
          "deprecated": "replaced by bitbucketCloud and bitbucketServer",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given Bitbucket instance",
                "type": "string"
              },
              "token": {
                "description": "Token used to authenticate requests.",
                "type": "string"
              },
              "apiBaseUrl": {
                "description": "The base url for the Bitbucket API, for example https://api.bitbucket.org/2.0",
                "type": "string"
              },
              "username": {
                "description": "The username to use for authenticated requests.",
                "type": "string"
              },
              "appPassword": {
                "description": "Bitbucket app password used to authenticate requests.",
                "type": "string"
              }
            }
          }
        },
        "bitbucketCloud": {
          "description": "Integration configuration for Bitbucket Cloud",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "username": {
                "description": "The username to use for authenticated requests.",
                "type": "string"
              },
              "appPassword": {
                "description": "Bitbucket Cloud app password used to authenticate requests.",
                "type": "string"
              }
            }
          }
        },
        "bitbucketServer": {
          "description": "Integration configuration for Bitbucket Server",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given Bitbucket Server instance",
                "type": "string"
              },
              "token": {
                "description": "Token used to authenticate requests.",
                "type": "string"
              },
              "username": {
                "description": "Username used to authenticate requests with Basic Auth.",
                "type": "string"
              },
              "password": {
                "description": "Password (or token as password) used to authenticate requests with Basic Auth.",
                "type": "string"
              },
              "apiBaseUrl": {
                "description": "The base url for the Bitbucket Server API, for example https://<host>/rest/api/1.0",
                "type": "string"
              }
            }
          }
        },
        "gerrit": {
          "description": "Integration configuration for Gerrit",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given Gerrit instance",
                "type": "string"
              },
              "baseUrl": {
                "description": "The base url for the Gerrit instance.",
                "type": "string"
              },
              "cloneUrl": {
                "description": "The base url for cloning repos.",
                "type": "string"
              },
              "username": {
                "description": "The username to use for authenticated requests.",
                "type": "string"
              },
              "password": {
                "description": "Gerrit password used to authenticate requests. This can be either a password\nor a generated access token.",
                "type": "string"
              }
            }
          }
        },
        "github": {
          "description": "Integration configuration for GitHub",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given GitHub instance",
                "type": "string"
              },
              "token": {
                "description": "Token used to authenticate requests.",
                "type": "string"
              },
              "apiBaseUrl": {
                "description": "The base url for the GitHub API, for example https://api.github.com",
                "type": "string"
              },
              "rawBaseUrl": {
                "description": "The base url for GitHub raw resources, for example https://raw.githubusercontent.com",
                "type": "string"
              },
              "apps": {
                "description": "GitHub Apps configuration",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "appId": {
                      "description": "The numeric GitHub App ID, string for environment variables",
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        { "type": "string" }
                      ]
                    },
                    "privateKey": {
                      "description": "The private key to use for auth against the app",
                      "type": "string"
                    },
                    "webhookSecret": {
                      "description": "The secret used for webhooks",
                      "type": "string"
                    },
                    "clientId": {
                      "description": "The client ID to use",
                      "type": "string"
                    },
                    "clientSecret": {
                      "description": "The client secret to use",
                      "type": "string"
                    },
                    "allowedInstallationOwners": {
                      "description": "List of installation owners allowed to be used by this GitHub app. The GitHub UI does not provide a way to list the installations.\nHowever you can list the installations with the GitHub API. You can find the list of installations here:\nhttps://api.github.com/app/installations\nThe relevant documentation for this is here.\nhttps://docs.github.com/en/rest/reference/apps#list-installations-for-the-authenticated-app--code-samples",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "gitlab": {
          "description": "Integration configuration for GitLab",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The host of the target that this matches on, e.g. \"gitlab.com\".",
                "type": "string"
              },
              "apiBaseUrl": {
                "description": "The base URL of the API of this provider, e.g.\n\"https://gitlab.com/api/v4\", with no trailing slash.\n\nMay be omitted specifically for public GitLab; then it will be deduced.",
                "type": "string"
              },
              "token": {
                "description": "The authorization token to use for requests to this provider.\n\nIf no token is specified, anonymous access is used.",
                "type": "string"
              },
              "baseUrl": {
                "description": "The baseUrl of this provider, e.g. \"https://gitlab.com\", which is\npassed into the GitLab client.\n\nIf no baseUrl is provided, it will default to https://${host}.",
                "type": "string"
              }
            }
          }
        },
        "googleGcs": {
          "description": "Integration configuration for Google Cloud Storage",
          "type": "object",
          "properties": {
            "clientEmail": {
              "description": "Service account email used to authenticate requests.",
              "type": "string"
            },
            "privateKey": {
              "description": "Service account private key used to authenticate requests.",
              "type": "string"
            }
          }
        },
        "awsS3": {
          "description": "Integration configuration for AWS S3 Service",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "endpoint": {
                "description": "AWS Endpoint.\nThe endpoint URI to send requests to. The default endpoint is built from the configured region.",
                "type": "string"
              },
              "s3ForcePathStyle": {
                "description": "Whether to use path style URLs when communicating with S3.\nDefaults to false.\nThis allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used.",
                "type": "boolean"
              },
              "accessKeyId": {
                "description": "Account access key used to authenticate requests.",
                "type": "string"
              },
              "secretAccessKey": {
                "description": "Account secret key used to authenticate requests.",
                "type": "string"
              },
              "roleArn": {
                "description": "ARN of the role to be assumed",
                "type": "string"
              },
              "externalId": {
                "description": "External ID to use when assuming role",
                "type": "string"
              }
            }
          }
        },
        "gitea": {
          "description": "Integration configuration for Gitea",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "host": {
                "description": "The hostname of the given Gitea instance",
                "type": "string"
              },
              "baseUrl": {
                "description": "The base url for the Gitea instance.",
                "type": "string"
              },
              "username": {
                "description": "The username to use for authenticated requests.",
                "type": "string"
              },
              "password": {
                "description": "Gitea password used to authenticate requests. This can be either a password\nor a generated access token.",
                "type": "string"
              }
            }
          }
        }
      }
    },
    "aws": {
      "description": "Configuration for access to AWS accounts",
      "type": "object",
      "properties": {
        "accountDefaults": {
          "description": "Defaults for retrieving AWS account credentials",
          "type": "object",
          "properties": {
            "roleName": {
              "description": "The IAM role to assume to retrieve temporary AWS credentials",
              "type": "string"
            },
            "partition": {
              "description": "The AWS partition of the IAM role, e.g. \"aws\", \"aws-cn\"",
              "type": "string"
            },
            "region": {
              "description": "The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. \"ap-northeast-1\"",
              "type": "string"
            },
            "externalId": {
              "description": "The unique identifier needed to assume the role to retrieve temporary AWS credentials",
              "type": "string"
            }
          }
        },
        "mainAccount": {
          "description": "Main account to use for retrieving AWS account credentials",
          "type": "object",
          "properties": {
            "accessKeyId": {
              "description": "The access key ID for a set of static AWS credentials",
              "type": "string"
            },
            "secretAccessKey": {
              "description": "The secret access key for a set of static AWS credentials",
              "type": "string"
            },
            "profile": {
              "description": "The configuration profile from a credentials file at ~/.aws/credentials and\na configuration file at ~/.aws/config.",
              "type": "string"
            },
            "region": {
              "description": "The STS regional endpoint to use for the main account, e.g. \"ap-northeast-1\"",
              "type": "string"
            }
          }
        },
        "accounts": {
          "description": "Configuration for retrieving AWS accounts credentials",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "accountId": {
                "description": "The account ID of the target account that this matches on, e.g. \"123456789012\"",
                "type": "string"
              },
              "accessKeyId": {
                "description": "The access key ID for a set of static AWS credentials",
                "type": "string"
              },
              "secretAccessKey": {
                "description": "The secret access key for a set of static AWS credentials",
                "type": "string"
              },
              "profile": {
                "description": "The configuration profile from a credentials file at ~/.aws/credentials and\na configuration file at ~/.aws/config.",
                "type": "string"
              },
              "roleName": {
                "description": "The IAM role to assume to retrieve temporary AWS credentials",
                "type": "string"
              },
              "partition": {
                "description": "The AWS partition of the IAM role, e.g. \"aws\", \"aws-cn\"",
                "type": "string"
              },
              "region": {
                "description": "The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. \"ap-northeast-1\"",
                "type": "string"
              },
              "externalId": {
                "description": "The unique identifier needed to assume the role to retrieve temporary AWS credentials",
                "type": "string"
              }
            }
          }
        }
      }
    },
    "airbrake": {
      "description": "Configuration options for the Airbrake plugin",
      "type": "object",
      "properties": {
        "apiKey": {
          "description": "The API Key to authenticate requests. More details on how to get this\nhere: https://airbrake.io/docs/api/#authentication",
          "type": "string"
        }
      }
    },
    "apacheAirflow": {
      "description": "Configurations for the Apache Airflow plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base url of the Apache Airflow installation.",
          "type": "string"
        }
      }
    },
    "azureDevOps": {
      "description": "Configuration options for the azure-devops-backend plugin",
      "type": "object",
      "properties": {
        "host": {
          "description": "The hostname of the given Azure instance",
          "type": "string"
        },
        "token": {
          "description": "Token used to authenticate requests.",
          "type": "string"
        },
        "organization": {
          "description": "The organization of the given Azure instance",
          "type": "string"
        }
      }
    },
    "catalog": {
      "description": "Configuration options for the catalog plugin.",
      "type": "object",
      "properties": {
        "rules": {
          "description": "Rules to apply to all catalog entities, from any location.\n\nAn undefined list of matchers means match all, an empty list of\nmatchers means match none.\n\nThis is commonly used to put in what amounts to an allowlist of kinds\nthat regular users of Backstage are permitted to register locations\nfor. This can be used to stop them from registering yaml files\ndescribing for example a Group entity called \"admin\" that they make\nthemselves members of, or similar.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "allow": {
                "description": "Allow entities of these particular kinds.\n\nE.g. [\"Component\", \"API\", \"Template\", \"Location\"]",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "locations": {
                "description": "Limit this rule to a specific location\n\nExample with a fixed location\n { \"type\": \"url\", \"exact\": \"https://github.com/a/b/blob/file.yaml\"}\n\nExample using a Regex\n { \"type\": \"url\", \"pattern\": \"https://github.com/org/*\\/blob/master/*.yaml\"}\n\nUsing both exact and pattern will result in an error starting the application",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "description": "The type of location, e.g. \"url\".",
                      "type": "string"
                    },
                    "exact": {
                      "description": "The exact location, e.g.\n\"https://github.com/org/repo/blob/master/users.yaml\".\n\nThe exact location can also be used to match on locations\nthat contain glob characters themselves, e.g.\n\"https://github.com/org/*\\/blob/master/*.yaml\".",
                      "type": "string"
                    },
                    "pattern": {
                      "description": "The pattern allowed for the location, e.g.\n\"https://github.com/org/*\\/blob/master/*.yaml\".",
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "readonly": {
          "description": "Readonly defines whether the catalog allows writes after startup.\n\nSetting 'readonly=false' allows users to register their own components.\nThis is the default value.\n\nSetting 'readonly=true' configures catalog to only allow reads. This can\nbe used in combination with static locations to only serve operator\nprovided locations. Effectively this removes the ability to register new\ncomponents to a running backstage instance.",
          "type": "boolean"
        },
        "locations": {
          "description": "A set of static locations that the catalog shall always keep itself\nup-to-date with. This is commonly used for large, permanent integrations\nthat are defined by the Backstage operators at an organization, rather\nthan individual things that users register dynamically.\n\nThese have (optional) rules of their own. These override what the global\nrules above specify. This way, you can prevent everybody from register\ne.g. User and Group entities, except for one or a few static locations\nthat have those two kinds explicitly allowed.\n\nFor example:\n\n```yaml\nrules:\n  - allow: [Component, API, Template, Location]\nlocations:\n  - type: url\n    target: https://github.com/org/repo/blob/master/users.yaml\n    rules:\n      - allow: [User, Group]\n  - type: url\n    target: https://github.com/org/repo/blob/master/systems.yaml\n    rules:\n      - allow: [System]\n```",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "description": "The type of location, e.g. \"url\".",
                "type": "string"
              },
              "target": {
                "description": "The target URL of the location, e.g.\n\"https://github.com/org/repo/blob/master/users.yaml\".",
                "type": "string"
              },
              "rules": {
                "description": "Optional extra rules that apply to this particular location.\n\nThese override the global rules above.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "allow": {
                      "description": "Allow entities of these particular kinds.\n\nE.g. [\"Group\", \"User\"]",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "orphanStrategy": {
          "description": "The strategy to use for entities that are orphaned, i.e. no longer have\nany other entities or providers referencing them. The default value is\n\"keep\".",
          "enum": ["delete", "keep"],
          "type": "string"
        },
        "processingInterval": {
          "description": "The interval at which the catalog should process its entities."
        },
        "processors": {
          "type": "object",
          "description": "List of processor-specific options and attributes",
          "properties": {
            "awsOrganization": {
              "description": "AwsOrganizationCloudAccountProcessor configuration",
              "type": "object",
              "properties": {
                "provider": {
                  "type": "object",
                  "properties": {
                    "roleArn": {
                      "description": "The role to be assumed by this processor",
                      "type": "string"
                    }
                  }
                }
              }
            },
            "githubMultiOrg": {
              "description": "GithubMultiOrgReaderProcessor configuration",
              "type": "object",
              "properties": {
                "orgs": {
                  "description": "The configuration parameters for each GitHub org to process.",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "description": "The name of the GitHub org to process.",
                        "type": "string"
                      },
                      "groupNamespace": {
                        "description": "The namespace of the group created for this org.\n\nDefaults to org name if omitted.",
                        "type": "string"
                      },
                      "userNamespace": {
                        "description": "The namespace of the users created from this org.\n\nDefaults to empty string if omitted.",
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "ldapOrg": {
              "description": "LdapOrgReaderProcessor configuration",
              "type": "object",
              "properties": {
                "providers": {
                  "description": "The configuration parameters for each single LDAP provider.",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "target": {
                        "description": "The prefix of the target that this matches on, e.g.\n\"ldaps://ds.example.net\", with no trailing slash.",
                        "type": "string"
                      },
                      "bind": {
                        "description": "The settings to use for the bind command. If none are specified,\nthe bind command is not issued.",
                        "type": "object",
                        "properties": {
                          "dn": {
                            "description": "The DN of the user to auth as.\n\nE.g. \"uid=ldap-robot,ou=robots,ou=example,dc=example,dc=net\"",
                            "type": "string"
                          },
                          "secret": {
                            "description": "The secret of the user to auth as (its password).",
                            "type": "string"
                          }
                        }
                      },
                      "tls": {
                        "description": "TLS settings",
                        "type": "object",
                        "properties": {
                          "rejectUnauthorized": {
                            "type": "boolean"
                          }
                        }
                      },
                      "users": {
                        "description": "The settings that govern the reading and interpretation of users.",
                        "type": "object",
                        "properties": {
                          "dn": {
                            "description": "The DN under which users are stored.\n\nE.g. \"ou=people,ou=example,dc=example,dc=net\"",
                            "type": "string"
                          },
                          "options": {
                            "description": "The search options to use. The default is scope \"one\" and\nattributes \"*\" and \"+\".\n\nIt is common to want to specify a filter, to narrow down the set\nof matching items.",
                            "type": "object",
                            "properties": {
                              "scope": {
                                "enum": ["base", "one", "sub"],
                                "type": "string"
                              },
                              "filter": {
                                "type": "string"
                              },
                              "attributes": {
                                "anyOf": [
                                  {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  {
                                    "type": "string"
                                  }
                                ]
                              },
                              "sizeLimit": {
                                "type": "number"
                              },
                              "timeLimit": {
                                "type": "number"
                              },
                              "derefAliases": {
                                "type": "number"
                              },
                              "typesOnly": {
                                "type": "boolean"
                              },
                              "paged": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "pageSize": {
                                        "type": "number"
                                      },
                                      "pagePause": {
                                        "type": "boolean"
                                      }
                                    }
                                  },
                                  {
                                    "type": "boolean"
                                  }
                                ]
                              }
                            }
                          },
                          "set": {
                            "description": "JSON paths (on a.b.c form) and hard coded values to set on those\npaths.\n\nThis can be useful for example if you want to hard code a\nnamespace or similar on the generated entities.",
                            "type": "object"
                          },
                          "map": {
                            "description": "Mappings from well known entity fields, to LDAP attribute names",
                            "type": "object",
                            "properties": {
                              "rdn": {
                                "description": "The name of the attribute that holds the relative\ndistinguished name of each entry. Defaults to \"uid\".",
                                "type": "string"
                              },
                              "name": {
                                "description": "The name of the attribute that shall be used for the value of\nthe metadata.name field of the entity. Defaults to \"uid\".",
                                "type": "string"
                              },
                              "description": {
                                "description": "The name of the attribute that shall be used for the value of\nthe metadata.description field of the entity.",
                                "type": "string"
                              },
                              "displayName": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.displayName field of the entity. Defaults to\n\"cn\".",
                                "type": "string"
                              },
                              "email": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.email field of the entity. Defaults to\n\"mail\".",
                                "type": "string"
                              },
                              "picture": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.picture field of the entity.",
                                "type": "string"
                              },
                              "memberOf": {
                                "description": "The name of the attribute that shall be used for the values of\nthe spec.memberOf field of the entity. Defaults to \"memberOf\".",
                                "type": "string"
                              }
                            }
                          }
                        }
                      },
                      "groups": {
                        "description": "The settings that govern the reading and interpretation of groups.",
                        "type": "object",
                        "properties": {
                          "dn": {
                            "description": "The DN under which groups are stored.\n\nE.g. \"ou=people,ou=example,dc=example,dc=net\"",
                            "type": "string"
                          },
                          "options": {
                            "description": "The search options to use. The default is scope \"one\" and\nattributes \"*\" and \"+\".\n\nIt is common to want to specify a filter, to narrow down the set\nof matching items.",
                            "type": "object",
                            "properties": {
                              "scope": {
                                "enum": ["base", "one", "sub"],
                                "type": "string"
                              },
                              "filter": {
                                "type": "string"
                              },
                              "attributes": {
                                "anyOf": [
                                  {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  {
                                    "type": "string"
                                  }
                                ]
                              },
                              "sizeLimit": {
                                "type": "number"
                              },
                              "timeLimit": {
                                "type": "number"
                              },
                              "derefAliases": {
                                "type": "number"
                              },
                              "typesOnly": {
                                "type": "boolean"
                              },
                              "paged": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "pageSize": {
                                        "type": "number"
                                      },
                                      "pagePause": {
                                        "type": "boolean"
                                      }
                                    }
                                  },
                                  {
                                    "type": "boolean"
                                  }
                                ]
                              }
                            }
                          },
                          "set": {
                            "description": "JSON paths (on a.b.c form) and hard coded values to set on those\npaths.\n\nThis can be useful for example if you want to hard code a\nnamespace or similar on the generated entities.",
                            "type": "object"
                          },
                          "map": {
                            "description": "Mappings from well known entity fields, to LDAP attribute names",
                            "type": "object",
                            "properties": {
                              "rdn": {
                                "description": "The name of the attribute that holds the relative\ndistinguished name of each entry. Defaults to \"cn\".",
                                "type": "string"
                              },
                              "name": {
                                "description": "The name of the attribute that shall be used for the value of\nthe metadata.name field of the entity. Defaults to \"cn\".",
                                "type": "string"
                              },
                              "description": {
                                "description": "The name of the attribute that shall be used for the value of\nthe metadata.description field of the entity. Defaults to\n\"description\".",
                                "type": "string"
                              },
                              "type": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.type field of the entity. Defaults to \"groupType\".",
                                "type": "string"
                              },
                              "displayName": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.displayName field of the entity. Defaults to\n\"cn\".",
                                "type": "string"
                              },
                              "email": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.email field of the entity.",
                                "type": "string"
                              },
                              "picture": {
                                "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.picture field of the entity.",
                                "type": "string"
                              },
                              "memberOf": {
                                "description": "The name of the attribute that shall be used for the values of\nthe spec.parent field of the entity. Defaults to \"memberOf\".",
                                "type": "string"
                              },
                              "members": {
                                "description": "The name of the attribute that shall be used for the values of\nthe spec.children field of the entity. Defaults to \"member\".",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "microsoftGraphOrg": {
              "description": "MicrosoftGraphOrgReaderProcessor configuration",
              "deprecated": "Use `catalog.providers.microsoftGraphOrg` instead.",
              "type": "object",
              "properties": {
                "providers": {
                  "description": "The configuration parameters for each single Microsoft Graph provider.",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "target": {
                        "description": "The prefix of the target that this matches on, e.g.\n\"https://graph.microsoft.com/v1.0\", with no trailing slash.",
                        "type": "string"
                      },
                      "authority": {
                        "description": "The auth authority used.\n\nDefault value \"https://login.microsoftonline.com\"",
                        "type": "string"
                      },
                      "tenantId": {
                        "description": "The tenant whose org data we are interested in.",
                        "type": "string"
                      },
                      "clientId": {
                        "description": "The OAuth client ID to use for authenticating requests.",
                        "type": "string"
                      },
                      "clientSecret": {
                        "description": "The OAuth client secret to use for authenticating requests.",
                        "type": "string"
                      },
                      "userFilter": {
                        "description": "The filter to apply to extract users.\n\nE.g. \"accountEnabled eq true and userType eq 'member'\"",
                        "type": "string"
                      },
                      "groupFilter": {
                        "description": "The filter to apply to extract groups.\n\nE.g. \"securityEnabled eq false and mailEnabled eq true\"",
                        "type": "string"
                      },
                      "userSelect": {
                        "description": "The fields to be fetched on query.\n\nE.g. [\"id\", \"displayName\", \"description\"]",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "groupSearch": {
                        "description": "The search criteria to apply to extract users by groups memberships.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                        "type": "string"
                      },
                      "groupSelect": {
                        "description": "The fields to be fetched on query.\n\nE.g. [\"id\", \"displayName\", \"description\"]",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "userGroupMemberFilter": {
                        "description": "The filter to apply to extract users by groups memberships.\n\nE.g. \"displayName eq 'Backstage Users'\"",
                        "type": "string"
                      },
                      "userGroupMemberSearch": {
                        "description": "The search criteria to apply to extract groups.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "providers": {
          "type": "object",
          "description": "List of provider-specific options and attributes",
          "properties": {
            "awsS3": {
              "description": "AwsS3EntityProvider configuration\n\nUses \"default\" as default id for the single config variant.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "bucketName": {
                      "description": "(Required) AWS S3 Bucket Name",
                      "type": "string"
                    },
                    "prefix": {
                      "description": "(Optional) AWS S3 Object key prefix\nIf not set, all keys will be accepted, no filtering will be applied.",
                      "type": "string"
                    },
                    "region": {
                      "description": "(Optional) AWS Region.\nIf not set, AWS_REGION environment variable or aws config file will be used.",
                      "type": "string"
                    },
                    "accountId": {
                      "description": "(Optional) AWS Account id.\nIf not set, main account is used.",
                      "type": "string"
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the refresh."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "bucketName": {
                        "description": "(Required) AWS S3 Bucket Name",
                        "type": "string"
                      },
                      "prefix": {
                        "description": "(Optional) AWS S3 Object key prefix\nIf not set, all keys will be accepted, no filtering will be applied.",
                        "type": "string"
                      },
                      "region": {
                        "description": "(Optional) AWS Region.\nIf not set, AWS_REGION environment variable or aws config file will be used.",
                        "type": "string"
                      },
                      "accountId": {
                        "description": "(Optional) AWS Account id.\nIf not set, main account is used.",
                        "type": "string"
                      },
                      "schedule": {
                        "description": "(Optional) TaskScheduleDefinition for the refresh."
                      }
                    }
                  }
                }
              ]
            },
            "azureDevOps": {
              "description": "AzureDevopsEntityProvider configuration",
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "host": {
                    "description": "(Optional) The DevOps host; leave empty for `dev.azure.com`, otherwise set to your self-hosted instance host.",
                    "type": "string"
                  },
                  "organization": {
                    "description": "(Required) Your organization slug.",
                    "type": "string"
                  },
                  "project": {
                    "description": "(Required) Your project slug.",
                    "type": "string"
                  },
                  "repository": {
                    "description": "(Optional) The repository name. Wildcards are supported as show on the examples above.\nIf not set, all repositories will be searched.",
                    "type": "string"
                  },
                  "path": {
                    "description": "(Optional) Where to find catalog-info.yaml files. Wildcards are supported.\nIf not set, defaults to /catalog-info.yaml.",
                    "type": "string"
                  },
                  "schedule": {
                    "description": "(Optional) TaskScheduleDefinition for the refresh."
                  }
                }
              }
            },
            "bitbucketCloud": {
              "description": "BitbucketCloudEntityProvider configuration\n\nUses \"default\" as default id for the single config variant.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "catalogPath": {
                      "description": "(Optional) Path to the catalog file. Default to \"/catalog-info.yaml\".",
                      "type": "string"
                    },
                    "workspace": {
                      "description": "(Required) Your workspace.",
                      "type": "string"
                    },
                    "filters": {
                      "description": "(Optional) Filters applied to discovered catalog files in repositories.",
                      "type": "object",
                      "properties": {
                        "repoSlug": {
                          "description": "(Optional) Regular expression filter for the repository slug.",
                          "type": "string"
                        },
                        "projectKey": {
                          "description": "(Optional) Regular expression filter for the project key.",
                          "type": "string"
                        }
                      }
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the discovery."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "catalogPath": {
                        "description": "(Optional) Path to the catalog file. Default to \"/catalog-info.yaml\".",
                        "type": "string"
                      },
                      "workspace": {
                        "description": "(Required) Your workspace.",
                        "type": "string"
                      },
                      "filters": {
                        "description": "(Optional) Filters applied to discovered catalog files in repositories.",
                        "type": "object",
                        "properties": {
                          "repoSlug": {
                            "description": "(Optional) Regular expression filter for the repository slug.",
                            "type": "string"
                          },
                          "projectKey": {
                            "description": "(Optional) Regular expression filter for the project key.",
                            "type": "string"
                          }
                        }
                      },
                      "schedule": {
                        "description": "(Optional) TaskScheduleDefinition for the discovery."
                      }
                    }
                  }
                }
              ]
            },
            "bitbucketServer": {
              "description": "BitbucketServerEntityProvider configuration\n\nUses \"default\" as default id for the single config variant.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "catalogPath": {
                      "description": "(Optional) Path to the catalog file. Default to \"/catalog-info.yaml\".",
                      "type": "string"
                    },
                    "filters": {
                      "description": "(Optional) Filters applied to discovered catalog files in repositories.",
                      "type": "object",
                      "properties": {
                        "repoSlug": {
                          "description": "(Optional) Regular expression filter for the repository slug.",
                          "type": "string"
                        },
                        "projectKey": {
                          "description": "(Optional) Regular expression filter for the project key.",
                          "type": "string"
                        }
                      }
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the refresh."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "catalogPath": {
                        "description": "(Optional) Path to the catalog file. Default to \"/catalog-info.yaml\".",
                        "type": "string"
                      },
                      "filters": {
                        "description": "(Optional) Filters applied to discovered catalog files in repositories.",
                        "type": "object",
                        "properties": {
                          "repoSlug": {
                            "description": "(Optional) Regular expression filter for the repository slug.",
                            "type": "string"
                          },
                          "projectKey": {
                            "description": "(Optional) Regular expression filter for the project key.",
                            "type": "string"
                          }
                        }
                      },
                      "schedule": {
                        "description": "(Optional) TaskScheduleDefinition for the refresh."
                      }
                    }
                  }
                }
              ]
            },
            "gcp": {
              "description": "GCPCatalogModuleConfig configuration",
              "type": "object",
              "properties": {
                "gke": {
                  "description": "Config for GKE clusters",
                  "type": "object",
                  "properties": {
                    "parents": {
                      "description": "Locations to list clusters from",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the refresh."
                    }
                  }
                }
              }
            },
            "gerrit": {
              "description": "GerritEntityProvider configuration\n\nMaps provider id with configuration.",
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "host": {
                    "description": "(Required) The host of the Gerrit integration to use.",
                    "type": "string"
                  },
                  "query": {
                    "description": "(Required) The query to use for the \"List Projects\" API call. Used to limit the\nscope of the projects that the provider tries to ingest.",
                    "type": "string"
                  },
                  "branch": {
                    "description": "(Optional) Branch.\nThe branch where the provider will try to find entities. Defaults to \"master\".",
                    "type": "string"
                  }
                }
              }
            },
            "github": {
              "description": "GithubEntityProvider configuration\n\nUses \"default\" as default id for the single config variant.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "host": {
                      "description": "(Optional) The hostname of your GitHub Enterprise instance.\nDefault: `github.com`.",
                      "type": "string"
                    },
                    "organization": {
                      "description": "(Required) Name of your organization account/workspace.",
                      "type": "string"
                    },
                    "catalogPath": {
                      "description": "(Optional) Path where to look for `catalog-info.yaml` files.\nYou can use wildcards - `*` or `**` - to search the path and/or the filename\nDefault: `/catalog-info.yaml`.",
                      "type": "string"
                    },
                    "filters": {
                      "description": "(Optional) Filter configuration.",
                      "type": "object",
                      "properties": {
                        "branch": {
                          "description": "(Optional) String used to filter results based on the branch name.",
                          "type": "string"
                        },
                        "repository": {
                          "description": "(Optional) Regular expression used to filter results based on the repository name.",
                          "type": "string"
                        },
                        "allowForks": {
                          "description": "(Optional) Allow Forks to be evaluated.",
                          "type": "boolean"
                        },
                        "topic": {
                          "description": "(Optional) GitHub topic-based filters.",
                          "type": "object",
                          "properties": {
                            "include": {
                              "description": "(Optional) An array of strings used to filter in results based on their associated GitHub topics.\nIf configured, only repositories with one (or more) topic(s) present in the inclusion\nfilter will be ingested.\n\nIf `include` and `exclude` are used, `exclude` has higher priority.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "exclude": {
                              "description": "(Optional) An array of strings used to filter out results based on their associated GitHub topics.\nIf configured, all repositories _except_ those with one (or more) topics(s) present in\nthe exclusion filter will be ingested.\n\nIf `include` and `exclude` are used, `exclude` has higher priority.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the refresh."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "host": {
                        "description": "(Optional) The hostname of your GitHub Enterprise instance.\nDefault: `github.com`.",
                        "type": "string"
                      },
                      "organization": {
                        "description": "(Required) Name of your organization account/workspace.",
                        "type": "string"
                      },
                      "catalogPath": {
                        "description": "(Optional) Path where to look for `catalog-info.yaml` files.\nYou can use wildcards - `*` or `**` - to search the path and/or the filename\nDefault: `/catalog-info.yaml`.",
                        "type": "string"
                      },
                      "filters": {
                        "description": "(Optional) Filter configuration.",
                        "type": "object",
                        "properties": {
                          "branch": {
                            "description": "(Optional) String used to filter results based on the branch name.",
                            "type": "string"
                          },
                          "repository": {
                            "description": "(Optional) Regular expression used to filter results based on the repository name.",
                            "type": "string"
                          },
                          "allowForks": {
                            "description": "(Optional) GitHub topic-based filters.",
                            "type": "boolean"
                          },
                          "topic": {
                            "description": "(Optional) Allow Forks to be evaluated.",
                            "type": "object",
                            "properties": {
                              "include": {
                                "description": "(Optional) An array of strings used to filter in results based on their associated GitHub topics.\nIf configured, only repositories with one (or more) topic(s) present in the inclusion\nfilter will be ingested.\n\nIf `include` and `exclude` are used, `exclude` has higher priority.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "exclude": {
                                "description": "(Optional) An array of strings used to filter out results based on their associated GitHub topics.\nIf configured, all repositories _except_ those with one (or more) topics(s) present in\nthe exclusion filter will be ingested.\n\nIf `include` and `exclude` are used, `exclude` has higher priority.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "schedule": {
                        "description": "(Optional) TaskScheduleDefinition for the refresh."
                      }
                    }
                  }
                }
              ]
            },
            "githubOrg": {
              "description": "Configuration for catalogModuleGithubOrgEntityProvider",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "A stable id for this provider. Entities from this provider will\nbe associated with this ID, so you should take care not to change\nit over time since that may lead to orphaned entities and/or\nconflicts.",
                      "type": "string"
                    },
                    "githubUrl": {
                      "description": "The target that this provider should consume.",
                      "type": "string"
                    },
                    "orgs": {
                      "description": "The list of the GitHub orgs to consume. By default will consume all accessible\norgs on the given GitHub instance (support for GitHub App integration only).",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "schedule": {
                      "description": "The refresh schedule to use."
                    }
                  }
                },
                {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "A stable id for this provider. Entities from this provider will\nbe associated with this ID, so you should take care not to change\nit over time since that may lead to orphaned entities and/or\nconflicts.",
                        "type": "string"
                      },
                      "githubUrl": {
                        "description": "The target that this provider should consume.",
                        "type": "string"
                      },
                      "orgs": {
                        "description": "The list of the GitHub orgs to consume. By default will consume all accessible\norgs on the given GitHub instance (support for GitHub App integration only).",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "schedule": {
                        "description": "The refresh schedule to use."
                      }
                    }
                  }
                }
              ]
            },
            "gitlab": {
              "description": "GitlabDiscoveryEntityProvider configuration",
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "host": {
                    "description": "(Required) Gitlab's host name.",
                    "type": "string"
                  },
                  "group": {
                    "description": "(Optional) Gitlab's group[/subgroup] where the discovery is done.\nIf not defined the whole instance will be scanned.",
                    "type": "string"
                  },
                  "branch": {
                    "description": "(Optional) Default branch to read the catalog-info.yaml file.\nIf not set, 'master' will be used.",
                    "type": "string"
                  },
                  "entityFilename": {
                    "description": "(Optional) The name used for the catalog file.\nIf not set, 'catalog-info.yaml' will be used.",
                    "type": "string"
                  },
                  "schedule": {
                    "description": "(Optional) TaskScheduleDefinition for the refresh."
                  },
                  "projectPattern": {
                    "description": "(Optional) RegExp for the Project Name Pattern",
                    "type": "string"
                  },
                  "userPattern": {
                    "description": "(Optional) RegExp for the User Name Pattern",
                    "type": "string"
                  },
                  "groupPattern": {
                    "description": "(Optional) RegExp for the Group Name Pattern",
                    "type": "string"
                  },
                  "skipForkedRepos": {
                    "description": "(Optional) Skip forked repository",
                    "type": "boolean"
                  }
                }
              }
            },
            "microsoftGraphOrg": {
              "description": "MicrosoftGraphOrgEntityProvider configuration.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "target": {
                      "description": "The prefix of the target that this matches on, e.g.\n\"https://graph.microsoft.com/v1.0\", with no trailing slash.",
                      "type": "string"
                    },
                    "authority": {
                      "description": "The auth authority used.\n\nDefault value \"https://login.microsoftonline.com\"",
                      "type": "string"
                    },
                    "tenantId": {
                      "description": "The tenant whose org data we are interested in.",
                      "type": "string"
                    },
                    "clientId": {
                      "description": "The OAuth client ID to use for authenticating requests.",
                      "type": "string"
                    },
                    "clientSecret": {
                      "description": "The OAuth client secret to use for authenticating requests.",
                      "type": "string"
                    },
                    "queryMode": {
                      "description": "By default, the Microsoft Graph API only provides the basic feature set\nfor querying. Certain features are limited to advanced query capabilities\n(see https://docs.microsoft.com/en-us/graph/aad-advanced-queries)\nand need to be enabled.\n\nSome features like `$expand` are not available for advanced queries, though.",
                      "type": "string"
                    },
                    "user": {
                      "type": "object",
                      "properties": {
                        "expand": {
                          "description": "The \"expand\" argument to apply to users.\n\nE.g. \"manager\".",
                          "type": "string"
                        },
                        "filter": {
                          "description": "The filter to apply to extract users.\n\nE.g. \"accountEnabled eq true and userType eq 'member'\"",
                          "type": "string"
                        }
                      }
                    },
                    "group": {
                      "type": "object",
                      "properties": {
                        "expand": {
                          "description": "The \"expand\" argument to apply to groups.\n\nE.g. \"member\".",
                          "type": "string"
                        },
                        "filter": {
                          "description": "The filter to apply to extract groups.\n\nE.g. \"securityEnabled eq false and mailEnabled eq true\"",
                          "type": "string"
                        },
                        "search": {
                          "description": "The search criteria to apply to extract users by groups memberships.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                          "type": "string"
                        },
                        "select": {
                          "description": "The fields to be fetched on query.\n\nE.g. [\"id\", \"displayName\", \"description\"]",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "userGroupMember": {
                      "type": "object",
                      "properties": {
                        "filter": {
                          "description": "The filter to apply to extract users by groups memberships.\n\nE.g. \"displayName eq 'Backstage Users'\"",
                          "type": "string"
                        },
                        "search": {
                          "description": "The search criteria to apply to extract groups.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                          "type": "string"
                        }
                      }
                    },
                    "schedule": {
                      "description": "(Optional) TaskScheduleDefinition for the refresh."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "target": {
                        "description": "The prefix of the target that this matches on, e.g.\n\"https://graph.microsoft.com/v1.0\", with no trailing slash.",
                        "type": "string"
                      },
                      "authority": {
                        "description": "The auth authority used.\n\nDefault value \"https://login.microsoftonline.com\"",
                        "type": "string"
                      },
                      "tenantId": {
                        "description": "The tenant whose org data we are interested in.",
                        "type": "string"
                      },
                      "clientId": {
                        "description": "The OAuth client ID to use for authenticating requests.",
                        "type": "string"
                      },
                      "clientSecret": {
                        "description": "The OAuth client secret to use for authenticating requests.",
                        "type": "string"
                      },
                      "queryMode": {
                        "description": "By default, the Microsoft Graph API only provides the basic feature set\nfor querying. Certain features are limited to advanced query capabilities\n(see https://docs.microsoft.com/en-us/graph/aad-advanced-queries)\nand need to be enabled.\n\nSome features like `$expand` are not available for advanced queries, though.",
                        "type": "string"
                      },
                      "user": {
                        "type": "object",
                        "properties": {
                          "filter": {
                            "description": "The filter to apply to extract users.\n\nE.g. \"accountEnabled eq true and userType eq 'member'\"",
                            "type": "string"
                          }
                        }
                      },
                      "group": {
                        "type": "object",
                        "properties": {
                          "filter": {
                            "description": "The filter to apply to extract groups.\n\nE.g. \"securityEnabled eq false and mailEnabled eq true\"",
                            "type": "string"
                          },
                          "search": {
                            "description": "The search criteria to apply to extract users by groups memberships.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                            "type": "string"
                          },
                          "select": {
                            "description": "The fields to be fetched on query.\n\nE.g. [\"id\", \"displayName\", \"description\"]",
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "userGroupMember": {
                        "type": "object",
                        "properties": {
                          "filter": {
                            "description": "The filter to apply to extract users by groups memberships.\n\nE.g. \"displayName eq 'Backstage Users'\"",
                            "type": "string"
                          },
                          "search": {
                            "description": "The search criteria to apply to extract groups.\n\nE.g. \"\\\"displayName:-team\\\"\" would only match groups which contain '-team'",
                            "type": "string"
                          }
                        }
                      },
                      "schedule": {
                        "description": "(Optional) TaskScheduleDefinition for the refresh."
                      }
                    }
                  }
                }
              ]
            },
            "puppetdb": {
              "description": "PuppetDB Entity Provider configuration. Uses \"default\" as default ID for the single config variant.",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "baseUrl": {
                      "description": "(Required) The base URL of PuppetDB API instance.",
                      "type": "string"
                    },
                    "query": {
                      "description": "(Optional) PQL query to filter PuppetDB nodes.",
                      "type": "string"
                    },
                    "schedule": {
                      "description": "(Optional) Task schedule definition for the refresh."
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "baseUrl": {
                        "description": "(Required) The base URL of PuppetDB API instance.",
                        "type": "string"
                      },
                      "query": {
                        "description": "(Optional) PQL query to filter PuppetDB nodes.",
                        "type": "string"
                      },
                      "schedule": {
                        "description": "(Optional) Task schedule definition for the refresh."
                      }
                    }
                  }
                }
              ]
            }
          }
        },
        "import": {
          "description": "List of import flow specific options and attributes",
          "type": "object",
          "properties": {
            "entityFilename": {
              "description": "Catalog entity descriptor filename, defaults to \"catalog-info.yaml\"",
              "type": "string"
            },
            "pullRequestBranchName": {
              "description": "A branch name used in pull request when registering existing component via UI\nValid git refname required, see: https://git-scm.com/docs/git-check-ref-format\nDefaults to \"backstage-integration\"",
              "type": "string"
            }
          }
        }
      }
    },
    "ldap": {
      "description": "LdapOrgEntityProvider / LdapOrgReaderProcessor configuration",
      "type": "object",
      "properties": {
        "providers": {
          "description": "The configuration parameters for each single LDAP provider.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "target": {
                "description": "The prefix of the target that this matches on, e.g.\n\"ldaps://ds.example.net\", with no trailing slash.",
                "type": "string"
              },
              "bind": {
                "description": "The settings to use for the bind command. If none are specified,\nthe bind command is not issued.",
                "type": "object",
                "properties": {
                  "dn": {
                    "description": "The DN of the user to auth as.\n\nE.g. \"uid=ldap-robot,ou=robots,ou=example,dc=example,dc=net\"",
                    "type": "string"
                  },
                  "secret": {
                    "description": "The secret of the user to auth as (its password).",
                    "type": "string"
                  }
                }
              },
              "tls": {
                "description": "TLS settings",
                "type": "object",
                "properties": {
                  "rejectUnauthorized": {
                    "type": "boolean"
                  }
                }
              },
              "users": {
                "description": "The settings that govern the reading and interpretation of users.",
                "type": "object",
                "properties": {
                  "dn": {
                    "description": "The DN under which users are stored.\n\nE.g. \"ou=people,ou=example,dc=example,dc=net\"",
                    "type": "string"
                  },
                  "options": {
                    "description": "The search options to use. The default is scope \"one\" and\nattributes \"*\" and \"+\".\n\nIt is common to want to specify a filter, to narrow down the set\nof matching items.",
                    "type": "object",
                    "properties": {
                      "scope": {
                        "enum": ["base", "one", "sub"],
                        "type": "string"
                      },
                      "filter": {
                        "type": "string"
                      },
                      "attributes": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          {
                            "type": "string"
                          }
                        ]
                      },
                      "sizeLimit": {
                        "type": "number"
                      },
                      "timeLimit": {
                        "type": "number"
                      },
                      "derefAliases": {
                        "type": "number"
                      },
                      "typesOnly": {
                        "type": "boolean"
                      },
                      "paged": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "pageSize": {
                                "type": "number"
                              },
                              "pagePause": {
                                "type": "boolean"
                              }
                            }
                          },
                          {
                            "type": "boolean"
                          }
                        ]
                      }
                    }
                  },
                  "set": {
                    "description": "JSON paths (on a.b.c form) and hard coded values to set on those\npaths.\n\nThis can be useful for example if you want to hard code a\nnamespace or similar on the generated entities.",
                    "type": "object"
                  },
                  "map": {
                    "description": "Mappings from well known entity fields, to LDAP attribute names",
                    "type": "object",
                    "properties": {
                      "rdn": {
                        "description": "The name of the attribute that holds the relative\ndistinguished name of each entry. Defaults to \"uid\".",
                        "type": "string"
                      },
                      "name": {
                        "description": "The name of the attribute that shall be used for the value of\nthe metadata.name field of the entity. Defaults to \"uid\".",
                        "type": "string"
                      },
                      "description": {
                        "description": "The name of the attribute that shall be used for the value of\nthe metadata.description field of the entity.",
                        "type": "string"
                      },
                      "displayName": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.displayName field of the entity. Defaults to\n\"cn\".",
                        "type": "string"
                      },
                      "email": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.email field of the entity. Defaults to\n\"mail\".",
                        "type": "string"
                      },
                      "picture": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.picture field of the entity.",
                        "type": "string"
                      },
                      "memberOf": {
                        "description": "The name of the attribute that shall be used for the values of\nthe spec.memberOf field of the entity. Defaults to \"memberOf\".",
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "groups": {
                "description": "The settings that govern the reading and interpretation of groups.",
                "type": "object",
                "properties": {
                  "dn": {
                    "description": "The DN under which groups are stored.\n\nE.g. \"ou=people,ou=example,dc=example,dc=net\"",
                    "type": "string"
                  },
                  "options": {
                    "description": "The search options to use. The default is scope \"one\" and\nattributes \"*\" and \"+\".\n\nIt is common to want to specify a filter, to narrow down the set\nof matching items.",
                    "type": "object",
                    "properties": {
                      "scope": {
                        "enum": ["base", "one", "sub"],
                        "type": "string"
                      },
                      "filter": {
                        "type": "string"
                      },
                      "attributes": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          {
                            "type": "string"
                          }
                        ]
                      },
                      "sizeLimit": {
                        "type": "number"
                      },
                      "timeLimit": {
                        "type": "number"
                      },
                      "derefAliases": {
                        "type": "number"
                      },
                      "typesOnly": {
                        "type": "boolean"
                      },
                      "paged": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "pageSize": {
                                "type": "number"
                              },
                              "pagePause": {
                                "type": "boolean"
                              }
                            }
                          },
                          {
                            "type": "boolean"
                          }
                        ]
                      }
                    }
                  },
                  "set": {
                    "description": "JSON paths (on a.b.c form) and hard coded values to set on those\npaths.\n\nThis can be useful for example if you want to hard code a\nnamespace or similar on the generated entities.",
                    "type": "object"
                  },
                  "map": {
                    "description": "Mappings from well known entity fields, to LDAP attribute names",
                    "type": "object",
                    "properties": {
                      "rdn": {
                        "description": "The name of the attribute that holds the relative\ndistinguished name of each entry. Defaults to \"cn\".",
                        "type": "string"
                      },
                      "name": {
                        "description": "The name of the attribute that shall be used for the value of\nthe metadata.name field of the entity. Defaults to \"cn\".",
                        "type": "string"
                      },
                      "description": {
                        "description": "The name of the attribute that shall be used for the value of\nthe metadata.description field of the entity. Defaults to\n\"description\".",
                        "type": "string"
                      },
                      "type": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.type field of the entity. Defaults to \"groupType\".",
                        "type": "string"
                      },
                      "displayName": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.displayName field of the entity. Defaults to\n\"cn\".",
                        "type": "string"
                      },
                      "email": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.email field of the entity.",
                        "type": "string"
                      },
                      "picture": {
                        "description": "The name of the attribute that shall be used for the value of\nthe spec.profile.picture field of the entity.",
                        "type": "string"
                      },
                      "memberOf": {
                        "description": "The name of the attribute that shall be used for the values of\nthe spec.parent field of the entity. Defaults to \"memberOf\".",
                        "type": "string"
                      },
                      "members": {
                        "description": "The name of the attribute that shall be used for the values of\nthe spec.children field of the entity. Defaults to \"member\".",
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "codescene": {
      "description": "Configuration options for the CodeScene plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base url of the CodeScene installation.",
          "type": "string"
        }
      }
    },
    "costInsights": {
      "type": "object",
      "properties": {
        "engineerCost": {
          "type": "number"
        },
        "engineerThreshold": {
          "type": "number"
        },
        "baseCurrency": {
          "type": "object",
          "properties": {
            "locale": {
              "type": "string"
            },
            "options": {
              "type": "object",
              "properties": {
                "localeMatcher": {
                  "type": "string"
                },
                "style": {
                  "type": "string"
                },
                "currency": {
                  "type": "string"
                },
                "currencySign": {
                  "type": "string"
                },
                "useGrouping": {
                  "type": "boolean"
                },
                "minimumIntegerDigits": {
                  "type": "number"
                },
                "minimumFractionDigits": {
                  "type": "number"
                },
                "maximumFractionDigits": {
                  "type": "number"
                },
                "minimumSignificantDigits": {
                  "type": "number"
                },
                "maximumSignificantDigits": {
                  "type": "number"
                }
              }
            }
          }
        },
        "products": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "icon": {
                "enum": [
                  "compute",
                  "data",
                  "database",
                  "ml",
                  "search",
                  "storage"
                ],
                "type": "string"
              }
            }
          }
        },
        "metrics": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "default": {
                "type": "boolean"
              }
            }
          }
        },
        "currencies": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "unit": {
                "type": "string"
              },
              "kind": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              },
              "rate": {
                "type": "number"
              },
              "default": {
                "type": "boolean"
              }
            }
          }
        }
      }
    },
    "devTools": {
      "description": "DevTools configuration.",
      "type": "object",
      "properties": {
        "externalDependencies": {
          "description": "External dependency configuration.",
          "type": "object",
          "properties": {
            "endpoints": {
              "description": "The list of endpoints to check.",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "The name of the endpoint.",
                    "type": "string"
                  },
                  "type": {
                    "description": "Type of check to perform; currently fetch or ping",
                    "type": "string"
                  },
                  "target": {
                    "description": "The target of the endpoint; currently either a URL for fetch or server name for ping.",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "info": {
          "description": "Info configuration",
          "type": "object",
          "properties": {
            "packagePrefixes": {
              "description": "A list of package prefixes that DevTools will use for filtering all available dependencies\n(default is [\"@backstage\"])",
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "dynatrace": {
      "description": "dynatrace config",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "base url for links",
          "type": "string"
        }
      }
    },
    "events": {
      "type": "object",
      "properties": {
        "http": {
          "type": "object",
          "properties": {
            "topics": {
              "description": "Topics for which a route has to be registered\nat which we can receive events via HTTP POST requests\n(i.e. received from webhooks).",
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "modules": {
          "type": "object",
          "properties": {
            "awsSqs": {
              "description": "events-backend-module-aws-sqs plugin configuration.",
              "type": "object",
              "properties": {
                "awsSqsConsumingEventPublisher": {
                  "description": "Configuration for AwsSqsConsumingEventPublisher.",
                  "type": "object",
                  "properties": {
                    "topics": {
                      "description": "Contains a record per topic for which an AWS SQS queue\nshould be used as source of events.",
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "queue": {
                            "description": "(Required) Queue-related configuration.",
                            "type": "object",
                            "properties": {
                              "region": {
                                "description": "(Required) The region of the AWS SQS queue.",
                                "type": "string"
                              },
                              "url": {
                                "description": "(Required) The absolute URL for the AWS SQS queue to be used.",
                                "type": "string"
                              },
                              "visibilityTimeout": {
                                "description": "(Optional) Visibility timeout for messages in flight."
                              },
                              "waitTime": {
                                "description": "(Optional) Wait time when polling for available messages.\nDefault: 20 seconds."
                              }
                            }
                          },
                          "timeout": {
                            "description": "(Optional) Timeout for the task execution which includes polling for messages\nand publishing the events to the event broker\nand the wait time after empty receives.\n\nMust be greater than `queue.waitTime` + `waitTimeAfterEmptyReceive`."
                          },
                          "waitTimeAfterEmptyReceive": {
                            "description": "(Optional) Wait time before polling again if no message was received.\nDefault: 1 minute."
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "github": {
              "description": "events-backend-module-github plugin configuration.",
              "type": "object",
              "properties": {
                "webhookSecret": {
                  "description": "Secret token for webhook requests used to verify signatures.\n\nSee https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks\nfor more details.",
                  "type": "string"
                }
              }
            },
            "gitlab": {
              "description": "events-backend-module-gitlab plugin configuration.",
              "type": "object",
              "properties": {
                "webhookSecret": {
                  "description": "Secret token for webhook requests used to verify tokens.\n\nSee https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#validate-payloads-by-using-a-secret-token\nfor more details.",
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "explore": {
      "type": "object",
      "properties": {
        "tools": {
          "description": "Tools to be used for the explore tool provider.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "title": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "url": {
                "type": "string"
              },
              "image": {
                "type": "string"
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "lifecycle": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "fossa": {
      "type": "object",
      "properties": {
        "organizationId": {
          "description": "The organization id in fossa.",
          "type": "string"
        },
        "externalLinkBaseUrl": {
          "description": "The base url to use for external links (from Backstage to Fossa).",
          "type": "string"
        }
      }
    },
    "gocd": {
      "description": "Configurations for the GoCD plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base url of the GoCD installation.",
          "type": "string"
        }
      }
    },
    "ilert": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "Domain used by users to access iLert web UI.\nExample: https://my-app.ilert.com/",
          "type": "string"
        },
        "proxyPath": {
          "description": "Path to use for requests via the proxy, defaults to /ilert/api",
          "type": "string"
        }
      }
    },
    "jenkins": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "Default instance baseUrl, can be specified on a named instance called \"default\"",
          "type": "string"
        },
        "username": {
          "description": "Default instance username, can be specified on a named instance called \"default\"",
          "type": "string"
        },
        "apiKey": {
          "description": "Default Instance apiKey, can be specified on a named instance called \"default\"",
          "type": "string"
        },
        "instances": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "description": "Name of the instance, this will be used in an annotation on catalog entities to refer to jobs on this instance.\n\nUse a name of \"default\" to specify the jenkins instance details if the annotation doesn't explicitly name an\ninstance.",
                "type": "string"
              },
              "baseUrl": {
                "type": "string"
              },
              "username": {
                "type": "string"
              },
              "apiKey": {
                "type": "string"
              },
              "extraRequestHeaders": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "properties": {
                  "Authorization": {
                    "type": "string"
                  },
                  "authorization": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "kafka": {
      "type": "object",
      "properties": {
        "clusters": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "description": "Cluster name",
                "type": "string"
              },
              "dashboardUrl": {
                "description": "Cluster dashboard url",
                "type": "string"
              },
              "brokers": {
                "description": "List of brokers in the Kafka cluster to connect to.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "ssl": {
                "description": "Optional SSL connection parameters to connect to the cluster. Passed directly to Node tls.connect.\nSee https://nodejs.org/dist/latest-v8.x/docs/api/tls.html#tls_tls_createsecurecontext_options",
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "ca": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "key": {
                        "type": "string"
                      },
                      "cert": {
                        "type": "string"
                      },
                      "rejectUnauthorized": {
                        "type": "boolean"
                      }
                    }
                  },
                  {
                    "type": "boolean"
                  }
                ]
              },
              "sasl": {
                "description": "Optional SASL connection parameters.",
                "type": "object",
                "properties": {
                  "mechanism": {
                    "enum": ["plain", "scram-sha-256", "scram-sha-512"],
                    "type": "string"
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "clientId": {
          "description": "Client ID used to Backstage uses to identify when connecting to the Kafka cluster.",
          "type": "string"
        }
      }
    },
    "kubernetes": {
      "type": "object",
      "properties": {
        "objectTypes": {
          "type": "array",
          "items": {
            "enum": [
              "configmaps",
              "cronjobs",
              "customresources",
              "daemonsets",
              "deployments",
              "horizontalpodautoscalers",
              "ingresses",
              "jobs",
              "limitranges",
              "pods",
              "replicasets",
              "services",
              "statefulsets"
            ],
            "type": "string"
          }
        },
        "serviceLocatorMethod": {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "enum": ["multiTenant"]
            }
          }
        },
        "clusterLocatorMethods": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["config"]
                  },
                  "clusters": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "serviceAccountToken": {
                          "type": "string"
                        },
                        "authProvider": {
                          "enum": [
                            "aws",
                            "azure",
                            "google",
                            "googleServiceAccount",
                            "oidc",
                            "serviceAccount"
                          ],
                          "type": "string"
                        },
                        "oidcTokenProvider": {
                          "type": "string"
                        },
                        "skipTLSVerify": {
                          "type": "boolean"
                        },
                        "skipMetricsLookup": {
                          "type": "boolean"
                        },
                        "caData": {
                          "type": "string"
                        },
                        "caFile": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["catalog"]
                  }
                }
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["localKubectlProxy"]
                  }
                }
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["gke"]
                  },
                  "projectId": {
                    "type": "string"
                  },
                  "region": {
                    "type": "string"
                  },
                  "skipTLSVerify": {
                    "type": "boolean"
                  },
                  "skipMetricsLookup": {
                    "type": "boolean"
                  }
                }
              }
            ]
          }
        },
        "customResources": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "group": {
                "type": "string"
              },
              "apiVersion": {
                "type": "string"
              },
              "plural": {
                "type": "string"
              }
            }
          }
        },
        "apiVersionOverrides": {
          "description": "(Optional) API Version Overrides\nIf set, the specified api version will be used to make requests for the corresponding object.\nIf running a legacy Kubernetes version, you may use this to override the default api versions\nthat are not supported in your cluster.",
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "properties": {
            "pods": {
              "type": "string"
            },
            "services": {
              "type": "string"
            },
            "configmaps": {
              "type": "string"
            },
            "deployments": {
              "type": "string"
            },
            "limitranges": {
              "type": "string"
            },
            "replicasets": {
              "type": "string"
            },
            "horizontalpodautoscalers": {
              "type": "string"
            },
            "jobs": {
              "type": "string"
            },
            "cronjobs": {
              "type": "string"
            },
            "ingresses": {
              "type": "string"
            },
            "customresources": {
              "type": "string"
            },
            "statefulsets": {
              "type": "string"
            },
            "daemonsets": {
              "type": "string"
            }
          }
        }
      }
    },
    "linguist": {
      "description": "Configuration options for the linguist plugin",
      "type": "object",
      "properties": {
        "schedule": {},
        "batchSize": {
          "default": 20,
          "type": "number"
        },
        "useSourceLocation": {
          "default": false,
          "type": "boolean"
        },
        "age": {
          "description": "Refresh generated language breakdown"
        },
        "kind": {
          "default": "['API', 'Component', 'Template']",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "linguistJsOptions": {
          "description": "[linguist-js](https://www.npmjs.com/package/linguist-js) options"
        },
        "tagsProcessor": {
          "description": "Options for the tags processor",
          "type": "object",
          "properties": {
            "bytesThreshold": {
              "description": "Determines how many bytes of a language should be in a repo\nfor it to be added as an entity tag. Defaults to 0.",
              "type": "number"
            },
            "languageTypes": {
              "description": "The types of linguist languages that should be processed. Can be\nany of \"programming\", \"data\", \"markup\", \"prose\". Defaults to [\"programming\"].",
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "languageMap": {
              "description": "A custom mapping of linguist languages to how they should be rendered as entity tags.\nIf a language is mapped to '' it will not be included as a tag.",
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            },
            "cacheTTL": {
              "description": "How long to cache entity languages for in memory. Used to avoid constant db hits during\nprocessing. Defaults to 30 minutes."
            }
          }
        }
      }
    },
    "opencost": {
      "description": "Configurations for the OpenCost plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base URL for the OpenCost API",
          "type": "string"
        }
      }
    },
    "periskop": {
      "description": "Configuration options for the periskop plugin",
      "type": "object",
      "properties": {
        "instances": {
          "description": "Integration configuration for the periskop servers",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "description": "The name of the given Periskop instance",
                "type": "string"
              },
              "url": {
                "description": "The hostname of the given Periskop instance",
                "type": "string"
              }
            }
          }
        }
      }
    },
    "pagerDuty": {
      "description": "Configuration for the PagerDuty plugin",
      "type": "object",
      "properties": {
        "eventsBaseUrl": {
          "description": "Optional Events Base URL to override the default.",
          "type": "string"
        }
      }
    },
    "permission": {
      "description": "Configuration options for Backstage permissions and authorization",
      "type": "object",
      "properties": {
        "enabled": {
          "description": "Whether authorization is enabled in Backstage. Defaults to false, which means authorization\nrequests will be automatically allowed without invoking the authorization policy.",
          "type": "boolean"
        }
      }
    },
    "playlist": {
      "type": "object",
      "properties": {
        "title": {
          "description": "(Optional) The title that will shown in the UI; Defaults to`Playlist` if undefined.",
          "type": "string"
        }
      }
    },
    "proxy": {
      "type": "object",
      "properties": {
        "skipInvalidProxies": {
          "description": "Rather than failing to start up, the proxy backend will instead just warn on invalid endpoints.",
          "type": "boolean"
        },
        "reviveConsumedRequestBodies": {
          "description": "Revive request bodies that have already been consumed by earlier middleware.",
          "type": "boolean"
        },
        "endpoints": {
          "description": "A list of forwarding-proxies. Each key is a route to match,\nbelow the prefix that the proxy plugin is mounted on. It must\nstart with a '/'.",
          "type": "object",
          "additionalProperties": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "target": {
                    "description": "Target of the proxy. Url string to be parsed with the url module.",
                    "type": "string"
                  },
                  "headers": {
                    "description": "Object with extra headers to be added to target requests.",
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "properties": {
                      "Authorization": {
                        "type": "string"
                      },
                      "authorization": {
                        "type": "string"
                      },
                      "X-Api-Key": {
                        "type": "string"
                      },
                      "x-api-key": {
                        "type": "string"
                      }
                    }
                  },
                  "changeOrigin": {
                    "description": "Changes the origin of the host header to the target URL. Default: true.",
                    "type": "boolean"
                  },
                  "pathRewrite": {
                    "description": "Rewrite target's url path. Object-keys will be used as RegExp to match paths.\nIf pathRewrite is not specified, it is set to a single rewrite that removes the entire prefix and route.",
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "allowedMethods": {
                    "description": "Limit the forwarded HTTP methods, for example allowedMethods: ['GET'] to enforce read-only access.",
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "allowedHeaders": {
                    "description": "Limit the forwarded HTTP methods. By default, only the headers that are considered safe for CORS\nand headers that are set by the proxy will be forwarded.",
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              {
                "type": "string"
              }
            ]
          }
        }
      }
    },
    "rollbar": {
      "description": "Configuration options for the rollbar plugin",
      "type": "object",
      "properties": {
        "organization": {
          "description": "The Rollbar organization name. This can be omitted by using the `rollbar.com/project-slug` annotation.",
          "type": "string"
        },
        "accountToken": {
          "description": "The authentication token for accessing the Rollbar API",
          "type": "string"
        }
      }
    },
    "scaffolder": {
      "description": "Configuration options for the scaffolder plugin",
      "type": "object",
      "properties": {
        "defaultAuthor": {
          "description": "The commit author info used when new components are created.",
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "email": {
              "type": "string"
            }
          }
        },
        "defaultCommitMessage": {
          "description": "The commit message used when new components are created.",
          "type": "string"
        },
        "concurrentTasksLimit": {
          "description": "Sets the number of concurrent tasks that can be run at any given time on the TaskWorker.\n\nDefaults to 10.\n\nSet to 0 to disable task workers altogether.",
          "type": "number"
        }
      }
    },
    "confluence": {
      "description": "Configuration options for the Confluence to Markdown action",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base URL for accessing the Confluence API",
          "type": "string"
        },
        "auth": {
          "type": "object",
          "properties": {
            "type": {
              "description": "Authentication method - basic, bearer, username/password",
              "enum": ["basic", "bearer", "userpass"],
              "type": "string"
            },
            "token": {
              "description": "Token used for the basic and bearer auth methods",
              "type": "string"
            },
            "email": {
              "description": "Email used with the token for the basic auth method",
              "type": "string"
            },
            "username": {
              "description": "Username used with the Username/Password auth method",
              "type": "string"
            },
            "password": {
              "description": "Password used with the Username/Password auth method",
              "type": "string"
            }
          }
        }
      }
    },
    "search": {
      "description": "Configuration options for the search plugin",
      "type": "object",
      "properties": {
        "maxPageLimit": {
          "description": "Sets the maximum max page limit size. Defaults to 100.",
          "type": "number"
        },
        "permissions": {
          "description": "Options related to the search integration with the Backstage permissions system",
          "type": "object",
          "properties": {
            "queryLatencyBudgetMs": {
              "description": "Limits the amount of time the search backend will spend retrieving and\nauthorizing results from the search engine when permissions are\nenabled. When the latency of the query endpoint reaches this threshold,\nthe results obtained up until that point will be returned, even if the\npage is incomplete.\n\nThis limit is only expected to be hit for broad queries from users with\nextremely restrictive visibility, or for very high page offsets.",
              "default": 1000,
              "type": "number"
            }
          }
        },
        "query": {
          "description": "An object representing the default search query configuration.\nBy configuring and modifying the values of this object,\nyou can customize the default values of the search queries\nand define how it behaves by default.",
          "type": "object",
          "properties": {
            "pageLimit": {
              "description": "A number indicating the maximum number of results to be returned\nper page during pagination.",
              "enum": [10, 100, 25, 50],
              "type": "number"
            }
          }
        },
        "collators": {
          "type": "object",
          "properties": {
            "catalog": {
              "description": "Configuration options for `@backstage/plugin-search-backend-module-catalog`",
              "type": "object",
              "properties": {
                "locationTemplate": {
                  "description": "A templating string with placeholders, to form the final location of\nthe entity.\n\nDefaults to '/catalog/:namespace/:kind/:name'",
                  "type": "string"
                },
                "filter": {
                  "description": "A filter expression passed to the catalog client, to select what\nentities to collate.\n\nDefaults to no filter, ie indexing all entities.",
                  "type": "object",
                  "additionalProperties": true
                },
                "batchSize": {
                  "description": "The number of entities to process at a time. Keep this at a\nreasonable number to avoid overloading either the catalog or the\nsearch backend.\n\nDefaults to 500",
                  "type": "number"
                },
                "schedule": {
                  "description": "The schedule for how often to run the collation job."
                }
              }
            },
            "explore": {
              "description": "Configuration options for `@backstage/plugin-search-backend-module-explore`",
              "type": "object",
              "properties": {
                "schedule": {
                  "description": "The schedule for how often to run the collation job."
                }
              }
            },
            "techdocs": {
              "description": "Configuration options for `@backstage/plugin-search-backend-module-techdocs`",
              "type": "object",
              "properties": {
                "schedule": {
                  "description": "The schedule for how often to run the collation job."
                },
                "locationTemplate": {
                  "description": "A templating string with placeholders, to form the final location of\nthe entity.\n\nDefaults to `'/docs/:namespace/:kind/:name/:path'`.",
                  "type": "string"
                },
                "parallelismLimit": {
                  "description": "An abstract value that controls the concurrency level of the\ncollation process. Increasing this value will both increase the\nnumber of entities fetched at a time from the catalog, as well as how\nmany things are being processed concurrently.\n\nDefaults to `10`.",
                  "type": "number"
                },
                "legacyPathCasing": {
                  "description": "Defaults to `false`.",
                  "type": "boolean"
                }
              }
            }
          }
        },
        "elasticsearch": {
          "description": "Options for ElasticSearch",
          "type": "object",
          "properties": {
            "batchSize": {
              "description": "Batch size for elastic search indexing tasks. Defaults to 1000.",
              "type": "number"
            },
            "highlightOptions": {
              "description": "Options for configuring highlight settings\nSee https://www.elastic.co/guide/en/elasticsearch/reference/7.17/highlighting.html",
              "type": "object",
              "properties": {
                "fragmentSize": {
                  "description": "The size of the highlighted fragment in characters. Defaults to 1000.",
                  "type": "number"
                },
                "numFragments": {
                  "description": "Number of result fragments to extract. Fragments will be concatenated with `fragmentDelimiter`. Defaults to 1.",
                  "type": "number"
                },
                "fragmentDelimiter": {
                  "description": "Delimiter string used to concatenate fragments. Defaults to \" ... \".",
                  "type": "string"
                }
              }
            },
            "indexTemplates": {
              "description": "Elasticsearch specific index template bodies",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "body": {
                    "type": "object",
                    "properties": {
                      "index_patterns": {
                        "description": "Array of wildcard (*) expressions used to match the names of data streams and indices during creation.",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "composed_of": {
                        "description": "An ordered list of component template names.\nComponent templates are merged in the order specified,\nmeaning that the last component template specified has the highest precedence.",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "template": {
                        "description": "See available properties of template\nhttps://www.elastic.co/guide/en/elasticsearch/reference/7.15/indices-put-template.html#put-index-template-api-request-body",
                        "type": "object"
                      }
                    }
                  }
                }
              }
            },
            "clientOptions": {
              "description": "Miscellaneous options for the client",
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "ssl": {
                      "type": "object",
                      "properties": {
                        "rejectUnauthorized": {
                          "description": "If true the server will reject any connection which is not\nauthorized with the list of supplied CAs.",
                          "default": true,
                          "type": "boolean"
                        }
                      }
                    },
                    "provider": {
                      "type": "string",
                      "enum": ["elastic"]
                    },
                    "cloudId": {
                      "description": "Elastic.co CloudID\nSee: https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-connecting.html#authentication",
                      "type": "string"
                    },
                    "auth": {
                      "type": "object",
                      "properties": {
                        "username": {
                          "type": "string"
                        },
                        "password": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                {
                  "type": "object",
                  "properties": {
                    "ssl": {
                      "type": "object",
                      "properties": {
                        "rejectUnauthorized": {
                          "description": "If true the server will reject any connection which is not\nauthorized with the list of supplied CAs.",
                          "default": true,
                          "type": "boolean"
                        }
                      }
                    },
                    "provider": {
                      "type": "string",
                      "enum": ["aws"]
                    },
                    "node": {
                      "description": "Node configuration.\nURL AWS ES endpoint to connect to.\nEg. https://my-es-cluster.eu-west-1.es.amazonaws.com",
                      "type": "string"
                    }
                  }
                },
                {
                  "type": "object",
                  "properties": {
                    "ssl": {
                      "type": "object",
                      "properties": {
                        "rejectUnauthorized": {
                          "description": "If true the server will reject any connection which is not\nauthorized with the list of supplied CAs.",
                          "default": true,
                          "type": "boolean"
                        }
                      }
                    },
                    "node": {
                      "description": "Node configuration.\nURL/URLS to ElasticSearch node to connect to.\nEither direct URL like 'https://localhost:9200' or with credentials like 'https://username:password@localhost:9200'",
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        {
                          "type": "string"
                        }
                      ]
                    },
                    "auth": {
                      "description": "Authentication credentials for ElasticSearch\nIf both ApiKey/Bearer token and username+password is provided, tokens take precedence",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "username": {
                              "type": "string"
                            },
                            "password": {
                              "type": "string"
                            }
                          }
                        },
                        {
                          "type": "object",
                          "properties": {
                            "apiKey": {
                              "description": "Base64 Encoded API key to be used to connect to the cluster.\nSee: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html",
                              "type": "string"
                            }
                          }
                        }
                      ]
                    }
                  }
                },
                {
                  "type": "object",
                  "properties": {
                    "ssl": {
                      "type": "object",
                      "properties": {
                        "rejectUnauthorized": {
                          "description": "If true the server will reject any connection which is not\nauthorized with the list of supplied CAs.",
                          "default": true,
                          "type": "boolean"
                        }
                      }
                    },
                    "provider": {
                      "type": "string",
                      "enum": ["opensearch"]
                    },
                    "node": {
                      "description": "Node configuration.\nURL/URLS to OpenSearch node to connect to.\nEither direct URL like 'https://localhost:9200' or with credentials like 'https://username:password@localhost:9200'",
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        {
                          "type": "string"
                        }
                      ]
                    },
                    "auth": {
                      "description": "Authentication credentials for OpenSearch\nIf both ApiKey/Bearer token and username+password is provided, tokens take precedence",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "username": {
                              "type": "string"
                            },
                            "password": {
                              "type": "string"
                            }
                          }
                        },
                        {
                          "type": "object",
                          "properties": {
                            "apiKey": {
                              "type": "string"
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              ]
            }
          }
        },
        "pg": {
          "description": "Options for PG",
          "type": "object",
          "properties": {
            "highlightOptions": {
              "description": "Options for configuring highlight settings\nSee https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE",
              "type": "object",
              "properties": {
                "useHighlight": {
                  "description": "Used to enable to disable the highlight feature. The default value is true",
                  "type": "boolean"
                },
                "maxWords": {
                  "description": "Used to set the longest headlines to output. The default value is 35.",
                  "type": "number"
                },
                "minWords": {
                  "description": "Used to set the shortest headlines to output. The default value is 15.",
                  "type": "number"
                },
                "shortWord": {
                  "description": "Words of this length or less will be dropped at the start and end of a headline, unless they are query terms.\nThe default value of three (3) eliminates common English articles.",
                  "type": "number"
                },
                "highlightAll": {
                  "description": "If true the whole document will be used as the headline, ignoring the preceding three parameters. The default is false.",
                  "type": "boolean"
                },
                "maxFragments": {
                  "description": "Maximum number of text fragments to display. The default value of zero selects a non-fragment-based headline generation method.\nA value greater than zero selects fragment-based headline generation (see the linked documentation above for more details).",
                  "type": "number"
                },
                "fragmentDelimiter": {
                  "description": "Delimiter string used to concatenate fragments. Defaults to \" ... \".",
                  "type": "string"
                }
              }
            },
            "indexerBatchSize": {
              "description": "Batch size to use when indexing",
              "type": "number"
            }
          }
        }
      }
    },
    "sentry": {
      "description": "Configuration options for the sentry plugin",
      "type": "object",
      "properties": {
        "organization": {
          "description": "The 'organization' attribute",
          "type": "string"
        }
      }
    },
    "sonarqube": {
      "description": "Optional configurations for the SonarQube plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base url of the sonarqube installation. Defaults to https://sonarcloud.io.",
          "type": "string"
        },
        "externalBaseUrl": {
          "description": "The external url of the sonarqube installation.\nUse this if you want to use a different url for the frontend than the backend.",
          "type": "string"
        },
        "apiKey": {
          "description": "The api key to access the sonarqube instance under baseUrl.",
          "type": "string"
        },
        "instances": {
          "description": "The optional sonarqube instances.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "description": "The name of the sonarqube instance.",
                "type": "string"
              },
              "baseUrl": {
                "description": "The base url of the sonarqube instance.",
                "type": "string"
              },
              "externalBaseUrl": {
                "description": "The external url of the sonarqube instance.\nUse this if you want to use a different url for the frontend than the backend.",
                "type": "string"
              },
              "apiKey": {
                "description": "The api key to access the sonarqube instance.",
                "type": "string"
              }
            }
          }
        }
      }
    },
    "splunkOnCall": {
      "description": "Splunk On Call Plugin specific configs",
      "type": "object",
      "properties": {
        "eventsRestEndpoint": {
          "type": "string"
        }
      }
    },
    "stackoverflow": {
      "description": "Configuration options for the stack overflow plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The base url of the Stack Overflow API used for the plugin",
          "type": "string"
        },
        "apiKey": {
          "description": "The API key to authenticate to Stack Overflow API",
          "type": "string"
        },
        "teamName": {
          "description": "The name of the team for a Stack Overflow for Teams account",
          "type": "string"
        },
        "apiAccessToken": {
          "description": "The API Access Token to authenticate to Stack Overflow API",
          "type": "string"
        }
      }
    },
    "stackstorm": {
      "type": "object",
      "properties": {
        "webUrl": {
          "description": "StackStorm Web UI url\nUsed in links to StackStorm web UI",
          "type": "string"
        }
      }
    },
    "techdocs": {
      "description": "Configuration options for the techdocs plugin",
      "type": "object",
      "properties": {
        "builder": {
          "description": "Documentation building process depends on the builder attr",
          "enum": ["external", "local"],
          "type": "string"
        },
        "legacyUseCaseSensitiveTripletPaths": {
          "description": "Allows fallback to case-sensitive triplets in case of migration issues.",
          "type": "boolean"
        },
        "sanitizer": {
          "type": "object",
          "properties": {
            "allowedIframeHosts": {
              "description": "Allows iframe tag only for listed hosts\nExample:\n allowedIframeHosts: [\"example.com\"]\n this will allow all iframes with the host `example.com` in the src attribute",
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "generator": {
          "description": "Techdocs generator information",
          "type": "object",
          "properties": {
            "runIn": {
              "description": "Where to run the techdocs (mkdocs) generator",
              "enum": ["docker", "local"],
              "type": "string"
            },
            "dockerImage": {
              "description": "Override the default techdocs docker image",
              "type": "string"
            },
            "pullImage": {
              "description": "Pull the latest docker image",
              "type": "boolean"
            },
            "mkdocs": {
              "description": "Override behavior specific to mkdocs.",
              "type": "object",
              "properties": {
                "legacyCopyReadmeMdToIndexMd": {
                  "description": "(Optional and not recommended) Configures the techdocs generator to\nattempt to ensure an index.md exists falling back to using <docs-dir>/README.md\nor README.md in case a default <docs-dir>/index.md is not provided.\nNote that https://www.mkdocs.org/user-guide/configuration/#edit_uri behavior\nwill be broken in these scenarios.",
                  "type": "boolean"
                },
                "defaultPlugins": {
                  "description": "List of mkdocs plugins which should be added as default to all mkdocs.yml files.",
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "publisher": {
          "description": "Techdocs publisher information",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "enum": [
                    "awsS3",
                    "azureBlobStorage",
                    "googleGcs",
                    "local",
                    "openStackSwift"
                  ],
                  "type": "string"
                },
                "local": {
                  "type": "object",
                  "properties": {
                    "publishDirectory": {
                      "description": "Directory to store generated static files.",
                      "type": "string"
                    }
                  }
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": ["awsS3"]
                },
                "awsS3": {
                  "description": "Required when 'type' is set to awsS3",
                  "type": "object",
                  "properties": {
                    "accountId": {
                      "description": "(Optional) The AWS account ID where the storage bucket is located.\nCredentials for the account ID will be sourced from the 'aws' app config section.\nSee the\n[integration-aws-node package](https://github.com/backstage/backstage/blob/master/packages/integration-aws-node/README.md)\nfor details on how to configure the credentials in the app config.\nIf account ID is not set and no credentials are set, environment variables or aws config file will be used to authenticate.",
                      "type": "string"
                    },
                    "credentials": {
                      "description": "(Optional) Credentials used to access a storage bucket.\nThis section is now deprecated. Configuring the account ID is now preferred, with credentials in the 'aws'\napp config section.\nIf not set and no account ID is set, environment variables or aws config file will be used to authenticate.",
                      "type": "object",
                      "properties": {
                        "accessKeyId": {
                          "description": "User access key id",
                          "type": "string"
                        },
                        "secretAccessKey": {
                          "description": "User secret access key",
                          "type": "string"
                        },
                        "roleArn": {
                          "description": "ARN of role to be assumed",
                          "type": "string"
                        }
                      }
                    },
                    "bucketName": {
                      "description": "(Required) Cloud Storage Bucket Name",
                      "type": "string"
                    },
                    "region": {
                      "description": "(Optional) AWS Region.\nIf not set, AWS_REGION environment variable or aws config file will be used.",
                      "type": "string"
                    },
                    "endpoint": {
                      "description": "(Optional) AWS Endpoint.\nThe endpoint URI to send requests to. The default endpoint is built from the configured region.",
                      "type": "string"
                    },
                    "s3ForcePathStyle": {
                      "description": "(Optional) Whether to use path style URLs when communicating with S3.\nDefaults to false.\nThis allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used to host tech docs.",
                      "type": "boolean"
                    },
                    "sse": {
                      "description": "(Optional) AWS Server Side Encryption\nDefaults to undefined.\nIf not set, encrypted buckets will fail to publish.\nhttps://docs.aws.amazon.com/AmazonS3/latest/userguide/specifying-s3-encryption.html",
                      "enum": ["AES256", "aws:kms"],
                      "type": "string"
                    }
                  }
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": ["openStackSwift"]
                },
                "openStackSwift": {
                  "description": "Required when 'type' is set to openStackSwift",
                  "type": "object",
                  "properties": {
                    "credentials": {
                      "description": "(Required) Credentials used to access a storage bucket.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "(Required) Application Credential ID",
                          "type": "string"
                        },
                        "secret": {
                          "description": "(Required) Application Credential Secret",
                          "type": "string"
                        }
                      }
                    },
                    "containerName": {
                      "description": "(Required) Cloud Storage Container Name",
                      "type": "string"
                    },
                    "authUrl": {
                      "description": "(Required) Auth url sometimes OpenStack uses different port check your OpenStack apis.",
                      "type": "string"
                    },
                    "swiftUrl": {
                      "description": "(Required) Swift URL",
                      "type": "string"
                    }
                  }
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": ["azureBlobStorage"]
                },
                "azureBlobStorage": {
                  "description": "Required when 'type' is set to azureBlobStorage",
                  "type": "object",
                  "properties": {
                    "connectionString": {
                      "description": "(Optional) Connection string of the storage container.",
                      "type": "string"
                    },
                    "credentials": {
                      "description": "(Optional) Credentials used to access a storage container.",
                      "type": "object",
                      "properties": {
                        "accountName": {
                          "description": "Account access name",
                          "type": "string"
                        },
                        "accountKey": {
                          "description": "(Optional) Account secret primary key\nIf not set, environment variables will be used to authenticate.",
                          "type": "string"
                        }
                      }
                    },
                    "containerName": {
                      "description": "(Required) Cloud Storage Container Name",
                      "type": "string"
                    }
                  }
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": ["googleGcs"]
                },
                "googleGcs": {
                  "description": "Required when 'type' is set to googleGcs",
                  "type": "object",
                  "properties": {
                    "bucketName": {
                      "description": "(Required) Cloud Storage Bucket Name",
                      "type": "string"
                    },
                    "credentials": {
                      "description": "(Optional) API key used to write to a storage bucket.\nIf not set, environment variables will be used to authenticate.",
                      "type": "string"
                    },
                    "projectId": {
                      "description": "(Optional) GCP project ID that contains the bucket. Should be\nset if credentials is not set, or if the service account in\nthe credentials belongs to a different project to the bucket.",
                      "type": "string"
                    }
                  }
                }
              }
            }
          ]
        },
        "cache": {
          "type": "object",
          "properties": {
            "ttl": {
              "description": "The cache time-to-live for TechDocs sites (in milliseconds). Set this\nto a non-zero value to cache TechDocs sites and assets as they are\nread from storage.\n\nNote: you must also configure `backend.cache` appropriately as well,\nand to pass a PluginCacheManager instance to TechDocs Backend's\ncreateRouter method in your backend.",
              "type": "number"
            },
            "readTimeout": {
              "description": "The time (in milliseconds) that the TechDocs backend will wait for\na cache service to respond before continuing on as though the cached\nobject was not found (e.g. when the cache sercice is unavailable).\n\nDefaults to 1000 milliseconds.",
              "type": "number"
            }
          }
        }
      }
    },
    "vault": {
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The baseUrl for your Vault instance.",
          "type": "string"
        },
        "publicUrl": {
          "description": "The publicUrl for your Vault instance (Optional).",
          "type": "string"
        },
        "token": {
          "description": "The token used by Backstage to access Vault.",
          "type": "string"
        },
        "secretEngine": {
          "description": "The secret engine name where in vault. Defaults to `secrets`.",
          "type": "string"
        },
        "kvVersion": {
          "description": "The version of the K/V API. Defaults to `2`.",
          "enum": [1, 2],
          "type": "number"
        }
      }
    },
    "scorecards": {
      "description": "Extra configuration for score card plugin",
      "type": "object",
      "properties": {
        "jsonDataUrl": {
          "description": "The public absolute root URL with json file defining the score card entries.",
          "type": "string"
        },
        "wikiLinkTemplate": {
          "description": "The template for the link to the wiki, e.g. \"https://TBD/XXX/_wiki/wikis/XXX.wiki/{id}\"",
          "type": "string"
        }
      }
    },
    "travisci": {
      "description": "Configuration options for the travisci plugin",
      "type": "object",
      "properties": {
        "baseUrl": {
          "description": "The 'baseUrl' attribute. It should point to the address of the travis portal.\nIf not provided, frontend plugin will use 'https://travis-ci.com/'",
          "type": "string"
        }
      }
    }
  }
}
