Configuration
Sourcemeta One is designed around a GitOps workflow: all of its behavior is determined by the configuration file documented here, and runtime changes are not permitted. This ensures that your instances are fully reproducible, auditable, and version-controlled, just like any other part of your infrastructure.
Success
Because Sourcemeta One is entirely configured at build time (with changes applied only via a redeployment), it achieves significant performance advantages. Schemas are pre-optimized at build time, and the service itself is fully stateless, enabling effortless horizontal scaling and predictable performance under load.
This configuration file is designed to give you complete freedom to structure your instance in a way that best suits your organization. Compared to many other solutions, it imposes no artificial constraints on hierarchy, versioning, or schema organization. You can version and arrange your schemas however you like: by department, by function, in a flat structure, or in any other way you can think of. This allows your instance to reflect your company's needs rather than a pre-defined model.
Note
By convention, the name of the configuration file is one.json.
The JSON Schema that defines one.json is always available at /self. You can
explore the latest version at
https://schemas.sourcemeta.com/self.
Tip
A great way to learn what's possible is to explore the configuration file of the schemas.sourcemeta.com public example instance, which you can find on GitHub
one.json
The configuration file controls your entire instance through various top-level properties that define both global settings and content structure. For representing the contents of the instance, this file uses a hierarchical tree approach where you organise the contents of your instance using nested nodes. Each node in this tree serves as either a Collection (containing actual schemas) or a Page (acting as a directory that groups other pages and schema collections), giving you complete flexibility in structuring your instance.
Note
The /self namespace is reserved for the built-in HTTP API
and internal functionality. It is always present and cannot be
overridden by user content.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/url |
String | N/A | The absolute URL on which the instance will be served. Sourcemeta One will automatically add URI identifiers relative to this URL for every ingested schema. The absolute URL may have a path component. The path component of this URL is case-sensitive per RFC 3986 Β§6.2.2.1. Inside the instance's URL namespace (schema URIs the catalog owns), path lookups are case-insensitive | |
/extends |
Array | No | None | One or more configuration files to extend from. See the Extends section for more information |
/contents |
Object | No | None | The top-level Collections and Pages that compose the instance |
/html |
Object or Boolean | No | {} |
Settings for the HTML explorer. If set to false, the instance runs in headless mode. Enabling the HTML explorer implies the API must also be enabled. See the HTML section for more details |
/api |
Object or Boolean | No | {} |
Controls whether the HTTP API is accessible. If set to false, the JSON API is disabled. Can only be set to false when /html is also set to false |
/authentication (Enterprise) |
Array | No | None | A list of authentication policies that govern this instance. Anything not covered by a policy remains public. See the Authentication section for more details |
For example, a minimal configuration that mounts a single schema collection
(./schemas) at URL https://schemas.example.com/my-first-collection may look
like this, and a schema at ./schemas/foo.json will be available at
https://schemas.example.com/my-first-collection/foo.json:
{
"url": "https://schemas.example.com",
"contents": {
"my-first-collection": {
"path": "./schemas"
}
}
}
HTML
When enabled through the optional html top-level property, Sourcemeta One
generates an HTML explorer interface. Unlike the JSON API, this
explorer provides a user-friendly web interface for browsing and examining your
schemas. You can customize the explorer's appearance and behavior using the
configuration options detailed below.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/name |
String | No | Sourcemeta | The concise name of the instance. For example, the name of your organisation. This will be shown in the navigation bar in the HTML explorer |
/description |
String | No | The next-generation JSON Schema platform | A longer description of the instance. This will be shown in HTML meta tags |
/head |
String | No | None | An HTML snippet to include in the <head> section of the HTML explorer. Useful for website analytics purposes or for custom styles |
/hero |
String | No | None | An HTML snippet to render in the front page. Try to make this snippet as standalone as possible using style HTML attributes |
/action |
Object | No | None | A call-to-action button to render in the navigation bar of the HTML explorer |
/action/title |
String | Yes | N/A | The text of the call-to-action button |
/action/icon |
String | Yes | N/A | The icon name of the call-to-action button, which must match the name of an icon in the Bootstrap Icons collection |
/action/url |
String | Yes | N/A | The absolute URL of the call-to-action button |
Collections
A schema collection functions as a curated set of schemas that the instance ingests and serves at a specified location. Unlike pages, schema collections contain the actual schema definitions that power your instance.
Sourcemeta One supports JSON Schema Draft 3, Draft 4, Draft 6, Draft 7, 2019-09, and 2020-12, and custom meta-schemas based on those dialects.
Warning
Sourcemeta One maintains data integrity by rejecting any schemas that fail against their meta-schemas or that cannot be fully resolved during the ingestion process. For this reason, you may need to explicitly inform the instance about default dialects, base URIs, or custom overrides for schema reference resolution.
If you are facing any difficulties with this, don't hesitate in asking for help using GitHub Discussions. We are here to help!
Note
To consolidate differences across operating systems, Sourcemeta One assumes the file system is case-insensitive and will not distinguish between two schema URIs that only differ in casing. Furthermore, URI paths will be turned into lowercase.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/path |
String | include is set) |
N/A | The path (relative to the location of the configuration file) to the directory which includes the schemas for this collection. The directory will be recursively traversed in search of .json, .yaml, or .yml schemas |
/baseUri |
String | No | The top-level url |
The base URI of every schema file that is part of this collection, for rebasing purposes. If a schema defines an explicit identifier that is not relative to this base URI, the generation of the instance will fail |
/defaultDialect |
String | No | None | The default JSON Schema dialect URI Reference to use for schemas that do not declare the $schema keyword. Accepts a URI reference, which is rebased against the collection's baseUri (or the top-level url joined with the collection path) unless it names an official JSON Schema dialect |
/title |
String | No | None | The concise title of the schema collection |
/description |
String | No | None | A longer description of the schema collection. The web explorer renders this as Markdown |
/email |
String | No | None | The e-mail address associated with the schema collection |
/github |
String | No | None | The GitHub organisation or organisation/repository identifier associated with the schema collection |
/website |
String | No | None | The absolute URL to the website associated with the schema collection |
/include |
String | No | None | A jsonschema.json manifest definition to include in-place. See the Include section for more information. If this property is set, none of the other properties can be set (including path) |
/resolve |
Object | No | None | A URI-to-URI map to hook into the schema reference resolution process. See the Resolve section for more information |
/lint |
Object | No | None | Linting configuration for this schema collection. See the JSON Schema CLI configuration for more information |
/lint/rules (Enterprise) |
Array | No | None | An array of file paths (relative to the configuration file location) to custom linting rule definitions. See the Linter section for more information |
/ignore |
Array | No | None | An array of file paths (relative to the configuration file location) to exclude from the schema collection. See the JSON Schema CLI configuration for more information |
/x-sourcemeta-one:evaluate |
Boolean | No | true |
When set to false, disable the evaluation API for this schema collection. This is useful if you will never make use of the evaluation API and want to speed up the generation of the instance |
/x-sourcemeta-one:alert |
String | No | N/A | When set, provide a human-readable alert on both the API and the HTML explorer for every schema in the collection. This is useful to provide any important message to consumers. The web explorer renders this as Markdown |
/x-sourcemeta-one:priority |
Integer | No | 50 |
A hint, from 0 (least important) to 100 (most important), that signals the relative importance of this collection compared to others in the same instance. Consumers may use this to rank or filter collections |
Warning
To preserve scalability and encourage best practices in schema organisation, Sourcemeta One caps the number of immediate entries (schemas or subdirectories) within a single registry directory to 1,000 by default. Instead of placing a large number of schemas in a single flat directory, organise them into a tree of nested subdirectories. A large number of schemas spread across multiple levels of directories scales well.
Include
The include property enables modular schema collection management by
allowing you to extract collection definitions into separate jsonschema.json
files and reference them in-place. Unlike inline definitions, this approach
promotes reusability across multiple configuration files while maintaining
clean separation of concerns. Each included jsonschema.json file contains the
same properties as a standard schema collection definition, with Sourcemeta One
seamlessly integrating the external file's contents at the specified location
during processing. For example:
{
"url": "https://schemas.example.com",
"contents": {
"my-first-collection": {
"include": "./jsonschema.json"
}
}
}
{
"title": "My Schema Collection",
"path": "./schemas"
}
If a directory path is provided to the include property, the instance will
look for a file called jsonschema.json inside such directory.
If the included manifest does not declare the path property (nor contents
or a nested include), the collection defaults to the directory containing
the manifest itself, mirroring how the JSON Schema
CLI
interprets such configuration files.
Resolve
The resolve property is an advanced feature to hook into the schema reference
resolution process. When set, the object translates any reference that equals a
property name in the object to the corresponding property value.
This is useful when mounting two schema collections where one references the
other through an absolute URL. For example, IPTC's News in
JSON schemas contain $ref references to
https://geojson.org/schema/GeoJSON.json. If you also host a vendored copy of
the GeoJSON schemas, you can use resolve to route
those external references back into your instance instead of depending on a
resource outside your control:
{
"url": "https://schemas.example.com",
"contents": {
"geojson": {
"baseUri": "https://geojson.org/schema",
"path": "./vendor/geojson"
},
"ninjs": {
"baseUri": "http://www.iptc.org/std/ninjs",
"path": "./vendor/ninjs",
"resolve": {
"https://geojson.org/schema/GeoJSON.json": "/geojson/GeoJSON.json"
}
}
}
}
Linter
Enterprise
Custom linter rules are only available in the Enterprise edition. Learn more about commercial licensing.
Sourcemeta One ships with a growing comprehensive set of built-in universal
linting rules. The lint/rules property lets you extend that default set with
rules specific to your organisation: naming conventions, required annotations,
structural patterns, or any other constraint that matters to your governance
standards. Violations are surfaced alongside the built-in checks in the
registry's health analysis.
A custom rule is a JSON Schema file written in any supported dialect. During
indexing, each rule is evaluated against every subschema in every schema of the
collection. The rule must declare a title (used as the unique rule
identifier) and should include a description (shown to developers when a
violation is reported).
Note
Rules apply to every subschema individually, not to the top-level schema
document as a whole. For example, a rule that requires every subschema to
define title will be checked against every nested subschema too, not only
the root.
For example, say your organisation requires all schema property names to follow camelCase. Create a rule file like this:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "custom/all_properties_camelcase",
"description": "Ensure camelCase properties",
"properties": {
"properties": {
"propertyNames": {
"pattern": "^[a-z][a-zA-Z0-9]*$"
}
}
}
}
This rule targets subschemas that define properties and asserts that all
property names within must match the camelCase pattern. Because the rule is
evaluated against every subschema, it catches violations at every nesting
level. Then register it in your configuration file:
{
"url": "https://schemas.example.com",
"contents": {
"my-collection": {
"path": "./schemas",
"lint": {
"rules": [ "./rules/camelcase.json" ]
}
}
}
}
Rule file paths are relative to the configuration file location. You can list multiple rules in the array to enforce several constraints at once. Rule names must be unique across all rules in a collection.
Pages
A page functions as an organizational container within the instance. Unlike schema collections, pages don't contain schemas directlyβinstead, they group other pages or schema collections together. For instance, you might create a hierarchy of pages representing your organization's teams, where each team page contains the schema collections they own.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/title |
String | No | None | The concise title of the page |
/description |
String | No | None | A longer description of the page |
/email |
String | No | None | The e-mail address associated with the page |
/github |
String | No | None | The GitHub organisation or organisation/repository identifier associated with the page |
/website |
String | No | None | The absolute URL to the website associated with the page |
/contents |
Object | No | None | The nested Collections and Pages inside this page |
Authentication
Enterprise
Authentication is only available in the Enterprise edition. Learn more about commercial licensing.
Authentication supports three policy types. An apiKey policy grants access to a
consumer that presents a pre-shared key, a jwt policy grants access to a
consumer that presents a signed JSON Web Token, verified against the issuer's
published key set, and an oidc policy grants access to a user who signs in
through their identity provider in the browser. The first two admit machines that
present a credential on every request, while the third authenticates a user once
and then rides a session the instance establishes. Anything not covered by a
policy stays public, so the configuration only ever describes what to protect,
never what to expose. When a path is governed by more than one policy, the
policies are unioned, so a single collection can admit both a machine presenting a
credential and a user carrying a session.
The UNIX model: Visibility and access are kept separate, following the UNIX
filesystem model. A policy that governs a directory does not erase it from its
parent's listing. Just as ls reveals a directory you cannot cd into, a
consumer browsing the instance can tell that a governed directory exists, and
can see the names of the policies that govern it, much like UNIX shows the
owning group of a file you are not allowed to read. What stays hidden is the
content: the directory cannot be opened, nor its schemas read, without a valid
key. The policy names are disclosed on purpose, so that a consumer knows who to
ask for access. The keys themselves, and the environment variables behind them,
are never exposed.
Tip
If the descriptive metadata of a governed directory, such as its title and description, is itself sensitive, wrap it: put the policy on a deliberately generic outer container that carries little metadata, and nest the sensitive directories inside it. Outsiders then see only the bland container, while the inner names and descriptions stay behind the gate.
A policy governs a Collection or Page, or a namespace above them (the instance root governs everything). It cannot gate an individual path inside a collection: a collection is either public or private as a whole.
Every policy declares its type, a name, and the paths it governs,
regardless of type:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/type |
String | N/A | The policy type, one of apiKey, jwt, or oidc |
|
/name |
String | N/A | The policy name, surfaced in directory listings. Must consist of lowercase letters, digits, and hyphens. The name public is reserved |
|
/paths |
Array | N/A | The registry paths this policy governs, each rooted at /. Every path must be / itself (governing the whole instance) or name a known collection, page, or route |
API Key
Consumers present a key through the Authorization header using the Bearer
scheme (RFC 6750).
An apiKey policy declares the following additional properties:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/algorithm |
String | N/A | How a presented key is compared against the stored keys. Either identity (the environment variable holds the key verbatim) or sha256 (the environment variable holds the lowercase hexadecimal SHA-256 digest of the key) |
|
/keys |
Array | N/A | The keys this policy accepts, each read from an environment variable so that secrets never live in the configuration file | |
/keys/*/environmentVariable |
String | N/A | The name of the environment variable that holds the key, or its hash when algorithm is not identity |
Tip
To consume schemas from a gated instance in your projects, take a look at
our JSON Schema CLI and its
install
command, which supports authenticating against a registry using API keys
through the --header option.
For example, the following instance keeps /docs public, gates /partners
behind a single key, and protects /billing with both a plaintext key and a
pre-hashed one:
{
"url": "https://schemas.example.com",
"authentication": [
{
"type": "apiKey",
"algorithm": "identity",
"name": "partners",
"paths": [ "/partners" ],
"keys": [ { "environmentVariable": "ONE_PARTNERS_KEY" } ]
},
{
"type": "apiKey",
"algorithm": "identity",
"name": "billing-plain",
"paths": [ "/billing" ],
"keys": [ { "environmentVariable": "ONE_BILLING_KEY" } ]
},
{
"type": "apiKey",
"algorithm": "sha256",
"name": "billing-hashed",
"paths": [ "/billing" ],
"keys": [ { "environmentVariable": "ONE_BILLING_HASHED_KEY" } ]
}
],
"contents": {
"docs": { "path": "./schemas/docs" },
"partners": { "path": "./schemas/partners" },
"billing": { "path": "./schemas/billing" }
}
}
Tip
For a sha256 policy, store the lowercase hexadecimal digest of the key
rather than the key itself. For example, printf '%s' "your-key" | openssl
dgst -sha256 | awk '{print $NF}' prints the exact value to place in the
environment variable.
Note
Sourcemeta One intentionally does not rate limit authentication. Provided keys are high-entropy, guessing one is computationally infeasible, so throttling does not meaningfully strengthen key protection, and per-client counters would require the shared state that the stateless design avoids. That reasoning assumes strong keys, so generate them with ample entropy. Rate limiting still has real value as operational abuse control, against online guessing of a weak key, resource exhaustion, or a leaked key, but it belongs at the deployment edge rather than in the catalog. Comparable components take the same stance: the Confluent Schema Registry ships no built-in rate limiting and is fronted by a reverse proxy for it, and container registries throttle at the CDN edge. Put that protection in a reverse proxy, API gateway, or WAF in front of the instance.
JWT
A jwt policy grants access to machine consumers that present a signed JSON Web
Token (RFC 7519) through the
Authorization header using the Bearer scheme (RFC
6750), as issued by an OAuth 2.0
or OpenID Connect provider. Unlike an apiKey policy, no shared secret lives in
the configuration or the instance: the policy names a trusted issuer, and the
instance verifies each token against the public key set that issuer publishes,
fetched over HTTP at request time and cached.
A token is admitted only when its signature verifies against the issuer's key
set, its iss claim matches the policy's issuer, its aud claim includes the
policy's audience, its signature algorithm is one the policy allows, and it is
within its validity period. A token that fails any of these is denied, with the
same response as any other unauthenticated request.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/issuer |
String | N/A | The token issuer to trust, matched against the iss claim |
|
/audience |
String | N/A | The audience this instance identifies as. A token is accepted when its aud claim includes this value, so a token minted for several audiences at once is accepted as long as this one is among them |
|
/algorithms |
Array | N/A | The JSON Web Signature algorithms the policy accepts. One or more of RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, and EdDSA |
|
/jwksUri |
String | No | Discovered from the issuer | The URL of the issuer's JSON Web Key Set. When omitted, it is discovered from the issuer's OpenID Connect metadata at {issuer}/.well-known/openid-configuration |
For example, the following instance keeps /docs public, gates /partners
behind an API key, and protects /internal with a JWT policy that trusts a
single issuer and audience:
{
"url": "https://schemas.example.com",
"authentication": [
{
"type": "apiKey",
"algorithm": "identity",
"name": "partners",
"paths": [ "/partners" ],
"keys": [ { "environmentVariable": "ONE_PARTNERS_KEY" } ]
},
{
"type": "jwt",
"name": "internal",
"paths": [ "/internal" ],
"issuer": "https://accounts.example.com",
"audience": "https://schemas.example.com",
"algorithms": [ "RS256" ]
}
],
"contents": {
"docs": { "path": "./schemas/docs" },
"partners": { "path": "./schemas/partners" },
"internal": { "path": "./schemas/internal" }
}
}
Note
The key set is fetched from the issuer over HTTP and cached as soft state,
honouring the response's Cache-Control and refreshed when a token presents
an unrecognised key identifier, so that issuer key rotation is picked up
without restarting the instance.
OIDC
An oidc policy grants access to a user who signs in through an OpenID Connect
provider in the browser. Where an apiKey or jwt policy admits a machine that
presents a credential on every request, an oidc policy authenticates a user
once at their provider and then relies on a session the instance establishes and
signs itself. Until that session exists, a browser that navigates to a governed
page is sent to begin a login, while a request for the raw schema, or from a
machine, is denied like any other unauthenticated request.
The instance registers with the provider as a client, identified by its
clientId and the client secret shared with it. It trusts the issuer both as
the value of the token's iss claim and as the source of the provider's OpenID
Connect metadata at {issuer}/.well-known/openid-configuration, from which it
discovers the signing key set that verifies each identity token. The session that
follows is signed with a secret of the instance's own, unrelated to the provider.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
/title |
String | No | The policy name | A human readable version of the policy name |
/issuer |
String | N/A | The OpenID Connect issuer to trust, matched against the identity token's iss claim and used to discover the provider's metadata, including the signing key set that verifies tokens |
|
/clientId |
String | N/A | The client identifier registered with the provider for this instance | |
/clientSecret |
Object | N/A | The client secret shared with the provider, read from an environment variable so that it never lives in the configuration file | |
/clientSecret/environmentVariable |
String | N/A | The name of the environment variable that holds the client secret | |
/sessionSecret |
Object | N/A | The secret used to sign the session cookies this instance mints, read from an environment variable. This is the instance's own secret, unrelated to the provider | |
/sessionSecret/environmentVariable |
String | N/A | The name of the environment variable that holds the session signing secret |
For example, the following instance keeps /docs public, gates /partners
behind an API key, and protects /console with an oidc policy so that users
sign in through their identity provider to reach it:
{
"url": "https://schemas.example.com",
"authentication": [
{
"type": "apiKey",
"algorithm": "identity",
"name": "partners",
"paths": [ "/partners" ],
"keys": [ { "environmentVariable": "ONE_PARTNERS_KEY" } ]
},
{
"type": "oidc",
"name": "console",
"title": "Acme Single Sign-On",
"paths": [ "/console" ],
"issuer": "https://accounts.example.com",
"clientId": "schemas-registry",
"clientSecret": { "environmentVariable": "ONE_CONSOLE_CLIENT_SECRET" },
"sessionSecret": { "environmentVariable": "ONE_CONSOLE_SESSION_SECRET" }
}
],
"contents": {
"docs": { "path": "./schemas/docs" },
"partners": { "path": "./schemas/partners" },
"console": { "path": "./schemas/console" }
}
}
Tip
Because the policies covering a path are unioned, an oidc policy can sit
alongside an apiKey or jwt policy on the same path. The collection then
admits both a machine that presents a credential and a user who signs in, so
one endpoint can serve continuous integration and users at once.
Note
The session signing secret is the instance's own, unrelated to the provider. To rotate it without invalidating live sessions, the environment variable may hold several secrets, one per line, newest first. New session cookies are signed with the first, while existing cookies are accepted against any, so an old secret can be retired once the sessions signed with it have expired.
Extends
The extends property enables configuration inheritance, allowing you to build
upon existing configuration files for enhanced reusability and modularity. This
property accepts an array of file paths (relative from the configuration file
location). For example:
{
"url": "https://schemas.example.com",
"extends": [ "../path/to/my/other/config/one.json" ]
}
If a directory path is provided to the extends property, the instance will
look for a file called one.json inside such directory.
Note
Sourcemeta One processes these extensions through deep-merging, where each extended configuration file merges into the previous one in sequence, with your top-level configuration file taking final precedence over the combined result.