Skip to main content

Connector manifest

manifest.json declares everything about a connector. HTTP connectors write it by hand; LDAP, SCIM, SQL and flat-file connectors have it derived from their definition.json. This page lists every field. The JSON Schema is the machine-readable form, and Validation issues lists the rules that tie the manifest to your handlers.

Top level​

FieldTypeRequiredMeaning
keystringyesThe connector's key: lowercase letters, digits, _ and -, starting with a letter or digit. Cannot change.
versionintegeryesThe major version, from 1.
namestringyesDisplay name.
kindstringnohttp, ldap, scim, sql or flat-file. Absent means http.
descriptionstringnoOne or two sentences for the catalog.
iconstringno@ followed by the vendor's domain (Owlie shows that brand's logo), or an https:// image URL.
providesarrayyesCapabilities: sync, provision, notification. (login is accepted but not used by current connectors.)
protocolsarraynoHost capabilities the connector needs: http (the default), ldap, sql, s3, powershell. ldap, sql and powershell require a private-network gateway.
execution_targetsarraynoWhere it may run: cloud, gateway, or both (the default for HTTP). A connector whose protocols need a gateway may declare only gateway.
pagination_typestringnoDefault ctx.paginate style: cursor, next-token, offset-limit, page-number, link-header.
configobjectyesThe shared install configuration (below).
autharrayyesAuthentication options (below).
entitiesobjectyesEntities, keyed by entity key (below).
grant_kindsarraynoGrant kinds (below).
custom_opsarraynoCustom operations (below).
egressobjectnoHosts the connector may reach (below).
http_rate_limitsobjectnoRequest pacing (below).

Config​

config is { title?, description?, schema, help_uri? }. schema is a JSON Schema object; Owlie renders the install form from it. Useful property keywords:

KeywordEffect
title, description, examples, defaultLabel, help text, sample values and a default in the install form.
"format": "password", writeOnly, "x-sensitive": trueMarks a secret: masked, never shown again, never in logs. Any one of these marks it.
"x-secret-ref": trueThe value is the name of a secret held on a private-network gateway, which the gateway resolves itself.
"x-suffix": ".example.com"Shows a fixed suffix inside the input and stores only what the admin types.

Add "additionalProperties": false so an install cannot store settings the connector does not declare.

Auth​

Each entry of auth is one authentication option:

FieldMeaning
keyStable id of the option, such as api-token.
title, description, help_uriWhat the admin sees when choosing, and a link to the vendor's setup guide.
enabledSet to false to hide the option.
availabilitySet to "disabled" to take the option out of service without deleting it (see below). The only accepted value.
config{ title?, description?, schema }: the credentials and settings this option needs.
connectA browser consent step: oauth2_authorization_code, or { "custom": true }.
acquireGetting a token: oauth2_client_credentials, oauth2_jwt_bearer, oauth2_private_key_jwt, oauth2_password, or { "custom": true }.
credentialsBuilding credentials: static or oauth2_token_response, or { "custom": true }. Required on every option that gets a token.
refreshRenewing a token: oauth2_refresh_token or any acquire form, or { "custom": true }.
applyPutting credentials on requests, or { "custom": true }.
reject{ statuses?, error }: a response that means the vendor refused the credential, see Credential rejection.

Values inside stages are nodes: { "literal": value }, or { "expr": "expression" } over config (the shared and option configuration merged), credentials, token_response and auth (auth.key); the connect stage sees only config and auth (Expressions). A secret-bearing field must read a property marked secret; a literal secret is refused. The shared configuration and an option's configuration must not share a property name.

Stage fields​

Stage formFields
oauth2_client_credentialstoken_url, client_id, client_secret, scope, audience, client_auth (body or basic), grant_type (a literal; default client_credentials), extra_params
oauth2_jwt_bearertoken_url, service_account_email, private_key, delegated_admin_email, scopes, grant_type, issuer, subject, audience
oauth2_private_key_jwttoken_url, client_id, private_key (PKCS#8 PEM or JWK), key_id, algorithm (RS256, PS256 or ES256), scope, audience, claims, extra_params
oauth2_passwordtoken_url, username, password, client_id, client_secret, client_auth, scope, extra_params
oauth2_refresh_tokentoken_url, refresh_token, client_id, client_secret, scope, client_auth, extra_params
oauth2_authorization_codeauthorize_url, token_url, issuer, client_id, client_secret, client_auth, scopes, response_type, response_mode, redirect_uri, pkce, audience, token_request_body (form or json), token_response_format, extra_authorize_params, extra_token_params, callback_validation
staticA record of named values, each a node.
oauth2_token_responseaccess_token, refresh_token, expires_in, extra: where each comes from in the token response.
applyheader (a record of header names to nodes), query (a record of parameters to nodes), basic (username, password), base_url (a node), tls (cert, key)

client_auth: "basic" sends the client id and secret as an HTTP Basic header instead of form fields. extra_params adds vendor-specific form fields; it cannot override a field the stage sets. callback_validation selects one of Owlie's built-in callback checks for vendors that require one (shopify_hmac, intuit_realm). github_app_installation under connect is reserved for Owlie's GitHub connector.

A stage marked { "custom": true } needs a matching function in lib/auth-hooks.ts (Handler API).

Disabling an option​

"availability": "disabled" takes an option out of service while its declaration, handlers and tests stay in place. Owlie leaves a disabled option out of the authentication options it offers an admin, and refuses to save an install's configuration, or start or finish a browser consent, that selects it (Integration auth option is disabled). Leave the field out to keep the option available. It is separate from enabled, which hides a single option at runtime based on the install's configuration.

Credential rejection​

Owlie already treats a 401 or 403 as a refused credential: it refreshes the credentials and retries the request once. Some vendors refuse a credential with another status, or with a 200 whose body carries an error code. reject declares that shape:

  • statuses (optional): up to 8 distinct HTTP statuses, 100 to 599, that the rule applies to. Leave it out to check the response whatever its status.
  • error.pointer: a JSON pointer into the JSON response body, beginning with /, at most 8 segments deep. It may contain at most one * segment, which stands for every element of an array.
  • error.codes: 1 to 16 distinct strings. The rule matches when the value at the pointer equals one of them; a number in the body is compared as its text.
  • error.match: "all" or "any". Required when the pointer contains a *: "all" needs every element of the array to match, "any" at least one. An empty array, or a value that is not an array, never matches.

When a response matches, Owlie refreshes the credentials and sends the request again once. If the second response also matches, the request fails as an authentication error (AUTH_ERROR) that is not retried, whatever the HTTP status was. A response that your http_rate_limits already read as a rate limit is not treated as a credential rejection.

Declaring reject asserts that the vendor refused the request before running it, because Owlie sends the request again even when it is a write. Declare it only when the vendor's documentation says so, and cite that page in the connector's README.

Entities​

entities is an object keyed by entity key (user, group, role). Keys are singular, start with a letter, and are not grant, grants, connection or notification.

FieldMeaning
nameDisplay name.
descriptionWhat the entity is in the system.
is_accounttrue on exactly one entity: the account.
schemaJSON Schema of the entity's record (below).
identifier_pathsIdentifier property names in order. Always declare it: without it Owlie falls back to the properties marked x-identifier, and the copy of the schema Owlie stores for each install does not keep property order. Owlie keys a record by the first identifier that has a value, so a record whose first identifier is empty is keyed by the next one; make sure the first is always present.
display_pathsProperties used as the record's display name, in order. Defaults to properties marked x-display.
sync_supportsupports_incremental (the entity has fetchAllSince), supports_deleted, and fetch_options (filter with enabled, input_hint and help; fields), which let an install narrow what Sync reads.
sync_profileDefaults for the install's sync settings (below).
provisioning_profileThe account entity's provisioning settings (below).
create_semanticsAccount only: direct (the default), invite (creating sends an invitation; the account is pending until accepted), or external (accounts are created outside Owlie; the connector writes Grants only and has no create handler).
inviteAccount only, with invite: expiry_attribute (the record property holding when the invitation expires) and reinvite_op (a custom operation that resends it).
identifier_transitionAccount only: true when the id a create returns changes once the account is accepted.

Schema annotations​

AnnotationMeaning
"x-identifier": trueAn identifier. List the same properties, in order, in identifier_paths; the first is the external id.
"x-provider-stable-id": trueThe vendor keeps this identifier for the record's lifetime and never reuses it. Top-level identifier properties only, and not writeOnly or x-sensitive.
"x-display": trueUse as the record's display name.
readOnly: trueSet by the system; never written.
writeOnly: trueSent but never read back, such as a password.
"x-sensitive": trueMasked in logs and audit.
"x-provisioning"requiredOn (actions that require it: PROVISION, UPDATE_ATTRIBUTES), writableOn (the only actions that may write it), immutable (set once), passwordHistory (true when the connector applies the target's own password history rules to a password written here). Top-level properties only.
"x-reference"{ entity, attribute }: the property refers to another account of the same system (a manager). entity is the account entity; attribute is the referenced account's property that holds the value, or externalId.
"x-scope"{ entity }: on a Grant target, the property holding the external id of the entity that scopes the target, such as the organization that owns a role. Empty or null means unscoped. One readable, top-level string property per entity, fetched by Sync.

Sync profile​

On the account entity, sync_profile can set: target (IDENTITY, RESOURCE or HYBRID), resourceId, matchingRules, onMatchAction, onNoMatchAction, onIdentityMatchWithoutAssignedResourceAction, attributeMappings, fetchOptions, assignmentPolicy, and three expressions over the synced record: is_active, is_deleted and is_person (Expressions).

target decides what Sync does with accounts. RESOURCE is for a system people are given access to: each account is linked to an existing identity by matchingRules, each { identityField, externalExpression } (such as { "identityField": "email", "externalExpression": "email" }), an account that matches nobody is flagged, and the install's resource is bound to the job. IDENTITY is for a source of people: Sync updates matched identities and creates one for every unmatched account. HYBRID does both. Without a target, the default is IDENTITY with onMatchAction update and onNoMatchAction create, so a connector for a system people get access to must declare RESOURCE. An account whose target is RESOURCE or HYBRID needs is_active; without it, Sync cannot tell an active account from an inactive one. On other entities, sync_profile can set attrMappings, fetchOptions and assignmentPolicy. These are defaults; each install can change them.

Provisioning profile​

provisioning_profile is { version, operations }. operations may contain PROVISION, REVOKE, DISABLE, ENABLE, UPDATE_ATTRIBUTES, ADD_GRANTS, REMOVE_GRANTS and SET_GRANTS; Owlie plans only the operations listed. Each may carry before and after hook steps, each { type, op, params?, when? } with type InvokeConnectorOp (a custom operation) or OwlieFunction.

OperationExtra fields
PROVISIONprovision_mode (direct, invite or external, matching create_semantics), baseline
REVOKEremove_managed_grants, lifecycle_state_on_revoke (DISABLED or DELETED)

baseline.attributes maps each attribute to a leaf evaluated per identity: { "type": "expression", "value": "identity.email" }, or { "type": "usernameGenerator", "config": { "steps": [...], "maxAttempts": 50 } }. baseline.grants lists Grants every new account gets, each { kind, target: { entity, external_id }, qualifiers? }.

On the account, provisioning_profile can also hold a password block. When Owlie creates the account it generates a random password of initial_length characters (24 unless set, 12 to 128) and sends it to every path in paths (one to four credential properties, both writeOnly and x-sensitive); it keeps no copy. policy (min_length, classes) states the target's own password rules. link: "identity" makes the account follow the person's password changes, self_service lets the person set this account's password themselves, on_change holds plain values written with every password change, and history_check (person_changes, the default, always or never) says which changes must meet the target's password history rules. Accounts created outside Owlie take no password block.

Grant kinds​

FieldDefaultMeaning
keyrequiredStable name; also the Grant handlers' folder. Starts with a letter; letters, digits, _, -.
sourcerequiredThe entity that normally holds the Grant.
principal_types[source]Every entity that can hold it; must include source.
targetrequiredThe entity the Grant is on.
discovered_viarequiredThe entity whose sync returns these relationships.
fetch_modeper-entityper-entity (fetchRelationships on discovered_via) or embedded (in fetchAll pages).
qualifiers[]The assignment's details (below).
validators[]Rules across qualifiers (below).
writablefalseOwlie may add and remove it. Needs provision in provides and both Grant handlers.
membershipfalseThe principal holds every Grant the target holds.
membership_context[]Required single-valued qualifiers carried along membership as scope. Needs membership.
prerequisitenone{ kind, target_from_qualifier }: a Grant of this kind needs a Grant of kind, held by the same principal on the target its target_from_qualifier qualifier names, such as an organization role needing membership of that organization. Owlie adds it with the Grant unless the resource turns that off. kind must be writable; the qualifier must be a required, single-valued entity_ref.
hierarchyfalseThe principal is a child of the target; propagating Grants on the target cover it.
propagatesfalseGrants of this kind cover the target's descendants.
derivedfalseComputed by the connector; never writable.
via_membershiptransitiveHow far membership reaches: transitive, direct or none.
effective_accesstrueWhether effective-access answers read this kind.

Qualifiers​

FieldMeaning
nameUnique within the Grant kind.
schemastring, enum, boolean, number, instant, duration, entity_ref, set or record.
requiredEvery Grant must carry it.
slot_keyThe value distinguishes assignments that can exist side by side.
multi_valuedThe qualifier holds several values. Cannot be combined with slot_key.
values, order, defaultFor enum: the allowed values, their ranking from lowest to highest, and a default.
unitFor number: its unit.
entityFor entity_ref: the entity the value refers to. The value is that entity's external id.
patternFor string and entity_ref: a regular expression new Grants must match. Anchor it with ^ and $ when it guards a URL segment. Nested quantifiers ((a+)+), repeated groups with alternatives ((a|b)+) and backreferences are refused.
examplesRealistic values; each must match pattern or be one of values.
sourceWhere Sync reads the value in a relationship record. Default attrs.<name>; must start with attrs..

Validators​

Each validator is an object whose kind names the rule, plus that rule's fields, such as { "kind": "cardinality", "per": "principal", "max": 1 }.

kindFieldsRule
cardinalityper (principal or principal_target), maxAt most max Grants of this kind per principal, or per principal and target.
subseta, bQualifier a's values are a subset of qualifier b's. Both multi-valued.
numeric_relationa, op (lt, lte, eq, gte, gt), bA numeric relation between two number qualifiers.

Custom operations​

Each entry of custom_ops is { key, title?, description?, params_schema? }. params_schema is a JSON Schema for the parameters; Owlie checks them before the handler <account entity>.op.<key> runs. Custom operations run on the account entity only.

Egress​

egress is { auto?, manual? }. manual lists the domains the connector reaches. auto lists { domain, source } pairs that Owlie derives itself from literal URLs in the authentication stages (apply.base_url and the token stages' token_url), recording in source where each came from; it replaces any auto you write whenever it builds the connector. A host built by an expression, such as 'https://' + config.subdomain + '.example.com', yields no auto entry, so list its parent domain under manual.

In Owlie's cloud, a connector may reach only HTTPS hosts that equal or are subdomains of these domains, plus any an install lists in egress_domains. Owlie adds that field to the configuration schema of every connector that runs in its cloud, with your egress domains as its default, so a connector must not declare a property of that name. Redirects are checked the same way.

Rate limits​

http_rate_limits is { buckets, rules, quota? }.

  • A bucket is either a fixed budget, { key, limit, window_ms, burst }, or limits the vendor reports, { key, kind: "fixed_reset", feedback }. feedback.headers names the response headers for limit, remaining, reset and retry (time headers as { name, unit }, with unit delta_seconds, epoch_seconds or epoch_milliseconds). feedback.body reads error responses: statuses (200 to 599, up to 8), error ({ pointer, match?, codes }, a JSON pointer and the vendor's rate-limit codes; match as in Credential rejection), optional limit, remaining, reset and retry pointers, and optional default_retry_ms (1 to 900000): how long to wait before retrying when the response gives no retry time.
  • A rule is { methods, origin?, path, buckets }: uppercase HTTP methods, an optional HTTPS origin, a path where * matches one segment and a final ** matches the rest, and the buckets a matching request consumes.
  • quota groups integrations that share one vendor quota: { namespace, dimensions }, each dimension { source, field, meaning } with source config or binding.

Declare only limits the vendor documents. Fixed budgets are paced at 80% of the declared rate. Without a declaration, Owlie still backs off when the vendor answers 429.