ConfigNamespace common.config-namespace@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
network
Visibility
internal
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/common/config-namespace.v1.json

common.config-namespace@1 (AI Exchange D11): one service configuration namespace as openvibe-shared/config's summary() returns it (config-pg.js), plus `sealed`, `pins` and `schema`. GET /internal/config lists these for a service and GET /internal/config/:namespace returns one. Values are the active ones over the defaults, with every secret-class value replaced by its marker; a marker never carries the value. `sealed` says whether the service has a KEK so secrets are envelopes (false is the pre-D11 plaintext behaviour). `pins` names the keys whose x-env variable is set, so their effective value is the environment's and a write is 409 config.pinned_in_env. `schema` is the namespace's JSON Schema so a client can draw the form; its annotations are title, description, x-group, x-env, x-danger, x-bind and x-unit (nano_usd, ms, bps, seconds), and for the owner's Setup tab and the clear admin panel (openvibe-shared 4.125.0) x-owner-input ({ group, unlocks, get_it_at, get_it_how, test }: a field only the owner can give), x-required-for (the feature an unset field blocks), x-enum-labels ({ value: { label, description } }), x-advanced (folded under Advanced settings) and x-example (a placeholder; never on a secret).

Fields

FieldTypeRequiredDescriptionConstraints
servicestringyes
  • pattern ^[a-z][a-z0-9-]{1,39}$
namespacestringyes<service>.<name>, e.g. ai.exchange or live.site_settings.
  • pattern ^[a-z][a-z0-9-]{1,39}(\.[a-z0-9_-]+)+$
  • maxLength 120
revisioninteger | nullyesThe active revision; null before the namespace has one.
  • minimum 1
valuesobjectyesThe active values over the defaults, one member per key. A secret-class key's value is a marker, never the value.
classificationobjectyesEvery key of values, classified. A key the service does not classify is internal.
sealedbooleanyesTrue when the service has a KEK: secret-class values are stored as envelopes and only opened for a caller that needs them. False keeps the pre-D11 plaintext-inside-values_json behaviour, and the tab shows it in red.
pinsarray of stringyesThe keys whose x-env variable is set in the service process: their effective value is the environment's, read-only, and a write answers 409 config.pinned_in_env.
  • unique items
  • items: pattern ^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,127}$
schemaobject | nullyesThe namespace's JSON Schema, or null when it has none. Annotations the client may read: title, description, x-group, x-env, x-danger, x-bind (the key whose value the secret is bound to), x-unit (nano_usd, ms, bps or seconds), x-owner-input, x-required-for, x-enum-labels, x-advanced and x-example.
activeone ofThe active revision as a snapshot (common.config-snapshot@1), or null.
last_known_goodone ofThe last revision that activated cleanly (common.config-snapshot@1), or null.

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: empty-namespace
{
  "service": "ai",
  "namespace": "ai.exchange",
  "revision": null,
  "values": {},
  "classification": {},
  "sealed": false,
  "pins": [],
  "schema": null,
  "active": null,
  "last_known_good": null
}
Valid: live-site-settings
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "site_name": "OpenVibe.Live",
    "registration_open": true,
    "max_bitrate_kbps": 6000,
    "youtube_api_key": {
      "redacted": true,
      "fingerprint": "c61d1b1293d59c54c56624f6d6161b8af976449db60f230ed977dcf3ba4bd31b",
      "hint": "a1b2",
      "set_at": "2026-11-04T18:34:00.000Z",
      "set_by": {
        "type": "user",
        "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
      },
      "bound_to": "https://www.googleapis.com"
    },
    "home_banner": {
      "text": "Welcome",
      "link": "/about"
    }
  },
  "classification": {
    "site_name": "public",
    "registration_open": "public",
    "max_bitrate_kbps": "internal",
    "youtube_api_key": "secret",
    "home_banner": "public"
  },
  "sealed": true,
  "pins": [
    "youtube_api_key"
  ],
  "schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "site_name": {
        "type": "string",
        "title": "Site name",
        "description": "The name shown in the page header.",
        "x-group": "Site"
      },
      "registration_open": {
        "type": "boolean",
        "title": "Registration open",
        "x-group": "Site"
      },
      "max_bitrate_kbps": {
        "type": "integer",
        "title": "Maximum bitrate",
        "x-group": "Streaming",
        "x-unit": "bps",
        "x-danger": true
      },
      "youtube_api_key": {
        "type": "string",
        "title": "YouTube API key",
        "x-group": "Integrations",
        "x-env": "YOUTUBE_API_KEY",
        "x-bind": "base_url"
      },
      "base_url": {
        "type": "string",
        "title": "Base URL",
        "x-group": "Integrations"
      }
    }
  },
  "active": {
    "service": "live",
    "namespace": "live.site_settings",
    "revision": 12,
    "previous_revision": 11,
    "state": "active",
    "values": {
      "site_name": "OpenVibe.Live",
      "registration_open": true,
      "max_bitrate_kbps": 6000,
      "youtube_api_key": {
        "redacted": true,
        "fingerprint": "c61d1b1293d59c54c56624f6d6161b8af976449db60f230ed977dcf3ba4bd31b"
      },
      "home_banner": {
        "text": "Welcome",
        "link": "/about"
      }
    },
    "classification": {
      "site_name": "public",
      "registration_open": "public",
      "max_bitrate_kbps": "internal",
      "youtube_api_key": "secret",
      "home_banner": "public"
    },
    "checksum": "29cd8cc21471b306491daa584d01892c05b41e5e51d5bf83aaf5fc6f4a28ca87",
    "created_at": "2026-09-25T18:02:11.412Z",
    "created_by": {
      "type": "user",
      "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
    },
    "activated_at": "2026-09-25T18:02:11.530Z",
    "activated_by": {
      "type": "user",
      "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
    },
    "reason": "Raise the bitrate cap for the tournament",
    "error": null,
    "copied_from": null
  },
  "last_known_good": {
    "service": "live",
    "namespace": "live.site_settings",
    "revision": 12,
    "previous_revision": 11,
    "state": "active",
    "values": {
      "site_name": "OpenVibe.Live",
      "registration_open": true,
      "max_bitrate_kbps": 6000,
      "youtube_api_key": {
        "redacted": true,
        "fingerprint": "c61d1b1293d59c54c56624f6d6161b8af976449db60f230ed977dcf3ba4bd31b"
      },
      "home_banner": {
        "text": "Welcome",
        "link": "/about"
      }
    },
    "classification": {
      "site_name": "public",
      "registration_open": "public",
      "max_bitrate_kbps": "internal",
      "youtube_api_key": "secret",
      "home_banner": "public"
    },
    "checksum": "29cd8cc21471b306491daa584d01892c05b41e5e51d5bf83aaf5fc6f4a28ca87",
    "created_at": "2026-09-25T18:02:11.412Z",
    "created_by": {
      "type": "user",
      "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
    },
    "activated_at": "2026-09-25T18:02:11.530Z",
    "activated_by": {
      "type": "user",
      "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
    },
    "reason": "Raise the bitrate cap for the tournament",
    "error": null,
    "copied_from": null
  }
}
Rejected: extra-field
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "site_name": "OpenVibe.Live"
  },
  "classification": {
    "site_name": "public"
  },
  "sealed": true,
  "pins": [],
  "schema": null,
  "active": null,
  "last_known_good": null,
  "secret_values": {
    "youtube_api_key": "AIza-example-secret"
  }
}
Rejected: pins-not-keys
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "site_name": "OpenVibe.Live"
  },
  "classification": {
    "site_name": "public"
  },
  "sealed": true,
  "pins": [
    "not a key"
  ],
  "schema": null,
  "active": null,
  "last_known_good": null
}
Rejected: schema-string
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "site_name": "OpenVibe.Live"
  },
  "classification": {
    "site_name": "public"
  },
  "sealed": true,
  "pins": [],
  "schema": "object",
  "active": null,
  "last_known_good": null
}
Rejected: secret-value
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "youtube_api_key": {
      "redacted": true,
      "fingerprint": "c61d1b1293d59c54c56624f6d6161b8af976449db60f230ed977dcf3ba4bd31b",
      "value": "AIza-example-secret"
    }
  },
  "classification": {
    "youtube_api_key": "secret"
  },
  "sealed": true,
  "pins": [],
  "schema": null,
  "active": null,
  "last_known_good": null
}
Rejected: unknown-classification
{
  "service": "live",
  "namespace": "live.site_settings",
  "revision": 12,
  "values": {
    "site_name": "OpenVibe.Live"
  },
  "classification": {
    "site_name": "private"
  },
  "sealed": true,
  "pins": [],
  "schema": null,
  "active": null,
  "last_known_good": null
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('common.config-namespace@1', value);   // { valid, errors: [{ path, message }] }