Skip to content

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 πŸ”΄ Yes 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:

one.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 πŸ”΄ Yes (unless 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:

one.json
{
  "url": "https://schemas.example.com",
  "contents": {
    "my-first-collection": {
      "include": "./jsonschema.json"
    }
  }
}
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:

one.json
{
  "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:

rules/camelcase.json
{
  "$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:

one.json
{
  "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 πŸ”΄ Yes N/A The policy type, one of apiKey, jwt, or oidc
/name String πŸ”΄ Yes N/A The policy name, surfaced in directory listings. Must consist of lowercase letters, digits, and hyphens. The name public is reserved
/paths Array πŸ”΄ Yes 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 πŸ”΄ Yes 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 πŸ”΄ Yes 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 πŸ”΄ Yes 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:

one.json
{
  "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 πŸ”΄ Yes N/A The token issuer to trust, matched against the iss claim
/audience String πŸ”΄ Yes 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 πŸ”΄ Yes 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:

one.json
{
  "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 πŸ”΄ Yes 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 πŸ”΄ Yes N/A The client identifier registered with the provider for this instance
/clientSecret Object πŸ”΄ Yes 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 πŸ”΄ Yes N/A The name of the environment variable that holds the client secret
/sessionSecret Object πŸ”΄ Yes 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 πŸ”΄ Yes 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:

one.json
{
  "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:

one.json
{
  "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.