Skip to main content

Authoring API Egress

Authoring API egress lets Pipeline Authoring inspect and invoke an API connector's immutable contract without exposing target credentials, proxy credentials, reusable broker tokens, or arbitrary transport controls to the authoring runtime.

info

All public endpoints are mounted under /api/v1.0. Paths below omit that prefix for readability.

The public API manages routing profiles, connector bindings, and exact write grants. External API invocation itself is a Pipeline Authoring tool operation, not a general-purpose public HTTP proxy.

Security And Permission Model

OperationRequired authority
List egress profiles or active selector optionsSuperadmin.
Create, update, or delete an egress profileNon-impersonating superadmin.
Attach a profile to an API connectorConnector edit plus non-impersonating superadmin authority through the normal connector update endpoint.
Discover or invoke contract operations in Pipeline AuthoringConnector execute, access to the active authoring session, and an effective runtime profile that permits the tool and network effect.
Issue or revoke an API write grantConnector edit and a non-impersonating user.

Profile administration is instance-global. Connector contracts, credentials, sessions, and permission checks remain scoped to their owning Qarion resources. A profile stores routing policy, not a target credential.

Egress Profile Endpoints

MethodEndpointDescription
GET/authoring-egress-profilesList every profile and connector usage count.
GET/authoring-egress-profiles/optionsList active metadata-only selector options.
POST/authoring-egress-profilesCreate a profile.
PATCH/authoring-egress-profiles/{profile_id}Patch a profile.
DELETE/authoring-egress-profiles/{profile_id}Delete an unattached profile.

Create a profile

POST /authoring-egress-profiles
Content-Type: application/json
{
"name": "Customer APIs",
"slug": "customer-apis",
"description": "Proxy policy for reviewed customer-service APIs.",
"proxy_url": "https://authoring-proxy.internal:8443",
"allowed_https_hosts": [
"api.example.com",
"*.services.example.com"
],
"allow_private_destinations": false,
"is_active": true
}

slug is optional. When omitted, Qarion derives a unique candidate from the name. A duplicate slug returns 409.

proxy_url must be an HTTP or HTTPS origin. User information, credentials, paths, queries, fragments, malformed ports, encoded host tricks, whitespace, and control characters are rejected. The profile API does not accept proxy credentials.

allowed_https_hosts requires at least one exact hostname, IP literal, or *.domain pattern. URL syntax is not accepted in this field. Matching the profile allowlist does not bypass HTTPS validation, DNS resolution checks, or the private-destination policy.

The proxy is the authoritative connection-time DNS and address-policy boundary. It must reject CONNECT requests whose X-Qarion-Authoring-Destination-Policy-SHA256 header is absent or does not match the destination policy loaded by the proxy, and it must reject resolved private addresses unless allow_private_destinations is enabled. Qarion's broker still performs a bounded preflight lookup, but that lookup alone is not a substitute for proxy-side enforcement against DNS rebinding.

Profile response

{
"id": "2f3ee858-5ac4-4f7b-bd32-61b298dc9af2",
"name": "Customer APIs",
"slug": "customer-apis",
"description": "Proxy policy for reviewed customer-service APIs.",
"proxy_url": "https://authoring-proxy.internal:8443",
"allowed_https_hosts": [
"api.example.com",
"*.services.example.com"
],
"allow_private_destinations": false,
"is_active": true,
"connector_usage_count": 1,
"created_by_id": "e156f92e-ac68-4b42-8859-ecccf6b97d31",
"updated_by_id": "e156f92e-ac68-4b42-8859-ecccf6b97d31",
"created_at": "2026-08-12T08:00:00Z",
"updated_at": "2026-08-12T08:00:00Z"
}

The /options response contains only id, name, slug, and is_active, and returns active profiles only.

Update or deactivate a profile

PATCH accepts any subset of name, description, proxy_url, allowed_https_hosts, allow_private_destinations, and is_active. Fields present in the request cannot be null. Deactivating an attached profile makes new brokered operations fail closed without removing the connector binding.

An attached profile cannot be deleted. Detach it from every connector first, or use is_active: false when the routing policy must be disabled immediately.

Bind a Profile to an API Connector

API connector create and update contracts include authoring_egress_profile_id:

PATCH /connectors/spaces/{space_slug}/{connector_id}
Content-Type: application/json
{
"authoring_egress_profile_id": "2f3ee858-5ac4-4f7b-bd32-61b298dc9af2"
}

Only API connectors use this binding for Pipeline Authoring invocation. The referenced profile must exist and be active when it is attached; setting the field to null detaches it. Only a non-impersonating superadmin who also has connector edit can change the binding. Existing connectors remain unbound after migration. An unbound connector can retain its normal contract refresh and connection-test behavior, but Pipeline Authoring cannot invoke its operations through the broker.

The connector must also have an active immutable API contract snapshot and any authentication mode other than none must reference an active compatible credential in the same space. See Pipeline Authoring API.

API Operation Discovery And Effects

Pipeline Authoring exposes three typed authoring tools:

Tool behaviorEffect
List the active contract operationsRead-only metadata; no credential or connector config is returned.
Invoke a contract-classified readNo API operation grant; requires connector execute and runtime network permission.
Execute a contract-classified write or destructive operationRequires connector execute plus an exact grant issued through the public API.

The server derives read, write, or destructive from the immutable contract operation. The caller does not choose the HTTP method, destination, or effect. A stale snapshot ID/hash, changed operation, inactive credential, inactive profile, destination denial, or effect mismatch fails closed.

REST calls accept contract-declared path, query, safe-header, and body values. GraphQL accepts one selected-root operation without batching, fragments, or introspection. SOAP accepts one safe envelope containing the selected body operation. Authentication, cookie, host, and transport-sensitive headers are server-owned. Redirects are rejected.

Issue an API Write Grant

POST /connectors/spaces/{space_slug}/{connector_id}/authoring-api-grants
Content-Type: application/json
{
"invocation": {
"session_id": "e94d2689-dc72-4b74-85ab-b16a547ca3e7",
"workflow_run_id": "050ed4e0-dc5c-4470-b76e-08e215348129",
"connector_id": "79288eec-a68b-4423-82cb-039492ad04a3",
"contract_snapshot_id": "fab08a39-e561-4410-94e6-2afe14257ccd",
"contract_content_hash": "9a3f7d206db0e1b5f28edc592bc4e26d6d559961172d1e3ce28f4359227b91d4",
"operation_key": "updateCustomer",
"request": {
"path_parameters": {
"customer_id": "cus_123"
},
"query_parameters": {},
"header_parameters": {},
"body": {
"status": "active"
},
"graphql_variables": {}
},
"affected_scope": "customer cus_123 status",
"grant_id": null,
"confirmation": null,
"call_id": "review-update-customer-1"
},
"effect": "write",
"source_workflow_run_id": "050ed4e0-dc5c-4470-b76e-08e215348129",
"expires_at": "2026-08-12T12:00:00Z"
}

The route connector_id, invocation connector_id, session, actor, workflow, active contract, operation effect, profile, credential, destination policy, canonical request, and affected scope are resolved and cross-checked before issuance. expires_at must be in the future and no more than 24 hours away. affected_scope must be explicit rather than unspecified.

For a destructive operation, set effect to destructive and include the exact confirmation in the invocation:

{
"confirmation": "CONFIRM deleteCustomer"
}

Read operations reject grant issuance because they do not use side-effect grants. A grant request must not already include a grant_id.

Grant response

{
"id": "db1cab79-6a94-48b4-81d1-2b85f96ed4ea",
"session_id": "e94d2689-dc72-4b74-85ab-b16a547ca3e7",
"connector_id": "79288eec-a68b-4423-82cb-039492ad04a3",
"contract_snapshot_id": "fab08a39-e561-4410-94e6-2afe14257ccd",
"operation_key": "updateCustomer",
"effect": "write",
"affected_scope": "customer cus_123 status",
"request_hash": "ea94a92435e5119332ad9f595db092ac1c3977ab939219998cecea34f615d9a9",
"status": "pending",
"expires_at": "2026-08-12T12:00:00Z",
"created_at": "2026-08-12T08:05:00Z"
}

Grant Lifecycle

pending -> reserved -> consumed
|
+-> revoked
  • Reservation is one atomic conditional update matching every bound field.
  • A validation failure before credential acquisition or destination dispatch releases reserved back to pending.
  • Once OAuth or destination dispatch begins, the grant becomes consumed even when the remote outcome is uncertain.
  • Only a pending, unexpired, exactly matching grant can be reserved.
  • Only a pending grant can be revoked.
  • Grants are not reusable after consumption, revocation, expiry, or binding drift.

The binding includes actor, authoring session and workflow, connector, credential, egress profile, contract snapshot/hash, operation/effect, affected scope, canonical request hash, and current binding fingerprint. Changing any of those inputs requires a new grant.

Revoke a Pending Grant

DELETE /connectors/spaces/{space_slug}/{connector_id}/authoring-api-grants/{grant_id}

A successful revocation returns 204 No Content. A missing, reserved, consumed, revoked, or connector-mismatched grant returns 409 without changing the record.

Sanitized Invocation Results

Tool-visible results contain:

  • ok, connector/profile/contract/operation identities, and derived effect;
  • HTTP status and content type when available;
  • a bounded JSON, XML, or text sample;
  • response size and SHA-256 hash;
  • truncation, schema-validation, and redaction metadata; and
  • a safe error code and message.

The transport reads at most 1 MiB. The model-visible sample is limited to 32 KiB and structurally redacted with shared secret, PII, and PHI patterns. Binary and unsafe malformed XML bodies are not returned.

Audit events store redacted identity and topology metadata, effect, request/grant hashes and IDs, timing, status class, response size/hash, truncation, and redaction categories. They do not store raw request parameters or bodies, response bodies, authentication material, OAuth tokens, or proxy URLs.

Internal Worker Boundary

The authoring control plane exposes an internal command-scoped invocation route to database-less Pipeline Authoring workers. It requires the signed command to contain the exact invocation and either api.invoke.read or api.invoke.write, then returns only the sanitized broker result.

This internal route is not part of the versioned public API. Integrations must not call it, construct command tokens, or treat it as a reusable proxy. Use the Pipeline Authoring chat/runtime surface and the public grant endpoints above.

Generated-code validation is offline and does not call the broker or receive connector, credential, or proxy material.

Errors

StatusMeaning
400Invalid effect, grant expiry, affected scope, contract input, protocol request, operation selection, or out-of-scope broker input.
403Required connector permission, authoring session authority, network authority, destination policy, or write grant is absent.
404A profile CRUD target or route-authorized public resource was not found.
409Duplicate/attached profile, route or effect mismatch, stale binding, unavailable grant, or non-pending revocation.
422Profile or request schema validation failed.
502Brokered transport, redirect, response, or upstream processing failed.
504The allowed upstream destination timed out.

Invocation failures appear through the Pipeline Authoring tool result rather than as a public invocation endpoint response.