Skip to main content
Not yet released. This guide describes implemented changes awaiting rollout. Availability requires the corresponding backend and dashboard release.

Goal

Manage Support workspace grouping without granting access to conversations through organization membership.

Prerequisites

  • A platform user with a verified email for invitation acceptance.
  • The coordinated API and Support worker release containing migrations 000527 through 000538. These changes are implemented locally and have not been deployed.
  • Explicit workspace owner authority for attachment approval; organization configuration requires an organization owner or admin.

Workflow

1
Create an organization with POST /api/v1/support/organizations. The caller becomes its owner. List organizations and inspect organization membership before managing it.
2
Invite an admin or member through /organizations/{organizationID}/invitations. Return the one-time token to the intended recipient through your authorized process; the API sends no invitation message. Acceptance requires the signed-in verified account matching the invitation.
3
An organization admin requests an existing standalone workspace attachment through /organizations/{organizationID}/workspace-attachments. Its workspace owner lists pending requests and approves the exact request revision through /workspaces/{workspaceID}/organization-attachments/{attachmentID}/approve.
4
Inspect the organization workspace list. Organization membership adds no workspace membership or inbox grants. Use the existing workspace invitation and grant APIs for content access.
5
List /workspaces/{workspaceID}/roles to inspect the named permission catalog. Create a workspace role, assign its role_id with member_revision and role_revision to an existing non-owner membership through /members/{membershipID}/custom-role, and set explicit inbox grants. Detail reads expose role state and permitted actions; archival refuses active assignments.
6
Use /effective-permissions for current allow-list and denial state. Read organization audit history through /organizations/{organizationID}/audit with limit and after pagination.

Authority and recovery boundaries

An organization owner may transfer ownership to an active manually managed organization member. Ordinary member updates cannot disable or demote the owner. Organization attachment needs both organization administration and workspace ownership; one person may hold both roles. No email-domain grouping, cross-organization record movement, consolidated billing or implicit customer access is added. Custom roles are workspace-local and use explicit inbox grants; changing a role requires its current revision and cannot delegate permissions or inbox access beyond the actor’s authority. Existing workspace invitations recheck current inviter authority and verified recipient identity on acceptance. Organization roles use a separate organization permission catalog and never grant content access. Organization configuration updates require revision; role assignments bind both member and role revisions. The locally implemented identity continuation supports OIDC/SAML and a restricted SCIM profile; provider qualification is outstanding. Organization IP/audit/retention governance is implemented locally; EU placement controls are implemented locally with current resource/runtime blockers; shared recovery release and physical restoration measurements remain unfinished. Native provider adapters, community and developer foundations are implemented locally; external qualification remains outstanding. Two-party workspace detach uses /organizations/{organizationID}/workspace-detachments and rejects unresolved directory identity or mandatory-policy dependencies at request and completion. Migration 528 rollback disables custom-role memberships and refuses to discard explicit denials; an authorized operator must review denials and reassess membership access before rollback recovery.

Enterprise SSO and directory provisioning

Unreleased migrations 530–531 require the API and Support worker release, existing encryption key and HTTPS SUPPORT_ENTERPRISE_BASE_URL. Create OIDC/SAML connections under /organizations/{organizationID}/identity-connections. SP-initiated login validates signatures, issuer, audience, expiry and replay; explicit link_identity binds the validated subject to the current verified account. Email matching and JIT creation are disabled. Test before enabling. Enforcement requires owner SSO and a one-time recovery code. Staged rotation must pass a pending login test; commit revokes earlier Support attestations. Recovery only removes Support enforcement and is audited. Hosting sessions and customer/provider callbacks retain their boundaries. Remove mandatory SSO and staff IP policy before ownership transfer. Issue expiring directory tokens through /directory-tokens. SCIM base /support/enterprise/v1/scim/{organizationID} supports Users (userName, externalId, displayName, active), Groups (displayName, externalId, direct members), discovery, equality filters, pagination, transactional PATCH and optional ETags. Configure provider mappings to this declared profile; unsupported fields/operations return SCIM errors. Directory records cannot create platform accounts or link by email. Link an existing verified user explicitly at its directory revision. Group mappings require organization administration and separate current workspace owner/admin authority. Group removal preserves manual grants; deactivation suspends organization Support access and revokes Support attestations without changing hosting accounts. Synthetic protocol and actual PostgreSQL/HTTP tests pass locally. Entra, Okta and Google tenants are unavailable; interoperability and deployment remain unqualified. Google SSO and provisioning need separate qualification.

Organization IP, audit and retention governance

Unreleased migrations 532–534 add separate staff/machine IPv4 and IPv6 policies. Owner-only preview binds actor, session, origin and policy revision for five minutes; confirmed staff activation requires a purpose-bound recovery code and preserves the acting owner’s address. SUPPORT_TRUSTED_PROXY_CIDRS defaults empty: Support evaluates the captured socket peer and trusts forwarded chains only through explicitly configured proxies. Customer/provider callbacks retain their separate authentication. Organization audit includes actor, scope, target, outcome and safe change metadata. Audit-read permission controls JSONL export requests, detail and download. The existing worker leases/reclaims queued audit exports, rechecks authority/session/IP before publication and uses durable object deletion for cancellation/expiry. No immutability certification is claimed. Owners preview and confirm content, associated-attachment, audit and execution retention bounds. Workspace configuration permission can preview/confirm overrides within current organization bounds. Existing eligibility and changed impact are checked; previews cannot delete data. Existing workers redact content and enqueue object deletion; attachments can expire independently while parent text remains. No legal hold or indefinite retention is introduced. EU placement and recovery controls are implemented locally but remain unreleased and incomplete. Current verified resource, credential, independent authority and runtime bindings determine availability; unconfigured or stale coverage is unavailable. Recovery uses actual quarantine and current sealed authority, with null numerical RPO/RTO. Full shared-schema release is explicitly blocked until platform job and financial reconciliation is implemented. See Support EU placement and recovery for the current code, operator capture helper and remaining work.

App installations and merchant actions

Unreleased migration 535 adds encrypted workspace/environment/inbox app installations, declared consent, current revisions, inspect/reconnect/disable/uninstall and durable action receipts in the existing worker. Secret credentials never appear in normal reads. Callbacks verify provider signatures, deduplicate and requery provider state. Current functional adapters are Bachs, Paystack, Flutterwave, GitHub, GitLab, Jira, Linear, Shopify, WooCommerce, HubSpot, Salesforce, Slack and Teams; portable/helpdesk snapshot migration tools and private automation definitions cover the remaining scoped catalog; authorized provider qualification is outstanding. Bachs, Paystack and Flutterwave merchant credentials are separate from Support billing. Bachs uses explicit verified payment links because payment responses lack stable customer IDs; one non-failed refund per charge is supported. Flutterwave uses verified account/customer IDs and exact decimal amounts; refund callbacks need provider enablement. Explicit customer links replace email matching. Payment read, refund request and refund approval permissions are separate. Every refund requires a different current staff member approving the exact transaction, amount, currency and request revision. Provider timeouts become unknown and require read-only reconciliation; they are never automatically resubmitted. Refund dispatch rereads refundable balance and reserves locally completed amounts until the provider ledger catches up. GitHub OAuth uses fixed exact callbacks, PKCE, one-use state, a secure browser cookie and the original verified platform session. Local issue operations are limited to the intended repository and explicitly selected public Support messages. The OAuth repo scope is broader than those local actions and requires explicit consent. Expired OAuth credentials require reconnect; signed provider events requery current status and update matching authorized links. Uninstall queues OAuth token revocation; PAT and merchant key/webhook removal require the merchant dashboard. GitLab personal tokens bind a numeric project and require api scope; signed GitLab 19.0+ callbacks and durable self-token revocation are supported. Jira API tokens bind an exact cloud tenant, project and non-subtask issue type; Linear API keys bind a team UUID. These profiles expose only issue creation/link/status using selected public content, requery signed status events, and reject cross-project/team results. Wider provider token scopes remain explicit. Jira and Linear key/subscription removal requires provider administration. Shopify and WooCommerce expose order.read, order.link and paginated orders.list under order:read consent and current integration/conversation permissions. Explicit customer IDs replace email matching. Shopify uses fixed 2026-07 GraphQL queries, separates test/live order flags and returns financial/fulfilment context within provider-approved history. WooCommerce uses HTTPS read keys, public-destination checks and customer-filtered pages; guest orders and plugin fulfilment states are unsupported, and test stores require separate credentials. Signed store events requery and refresh matching local order receipts. Order mutations are excluded. HubSpot and Salesforce expose crm.contact/company read/create/update under explicit crm:read/write consent and current integration/conversation authority. Link contacts by provider ID and companies through verified record links. Fixed mappings include contact names/phone and company name/website/industry; no email merging or Support contact overwrite. Updates require the observed modified_at; Salesforce adds a conditional update header, while HubSpot retains a preflight race limitation. Bounded worker polling requires the original active actor/session and unchanged links. Tokens are operator-managed; automatic OAuth refresh and CRM callbacks are unavailable. Interrupted writes become unknown and are never automatically repeated. Slack and Teams bind one fixed workspace/team channel to dedicated credentials. escalation.send uses a title and optional explicitly selected public messages; private/redacted content and caller destinations are rejected. Plain Slack text and escaped Teams HTML include a server-generated authenticated Support conversation API link. Current staff can acknowledge a succeeded receipt at its revision under escalation:acknowledge consent; acknowledgement does not change assignment. Native provider actions are unsupported. Slack uninstall revokes its dedicated token durably; Teams tokens remain operator-managed. Unknown sends are never repeated automatically. Private Zapier, n8n and Make definitions/examples use explicit machine credentials, /support/machine/v1/events metadata pagination and existing idempotent ticket actions. The feed excludes payloads, private notes, erased contacts and inaccessible inboxes. Credential creation checks the issuer’s active session, delegated scopes and inbox grants; workspace suspension denies machine access. Latest-100 polling profiles have an explicit volume limit. Durable cursors need successful downstream processing; provider private-account/CLI qualification and publication remain outstanding. App receipt detail/list reads preserve current conversation and operation permissions. Confirmed execution retention scrubs completed non-financial bodies while retaining uniqueness receipts. Financial evidence is an explicit exception. Customer erasure removes links and cancels pending work; selected message redaction clears retained issue payloads. Data already sent to a provider needs that provider’s erasure workflow. Synthetic provider and authenticated PostgreSQL tests passed for approvals, idempotency, signed events, uninstall, OAuth replay/session binding and unknown refund reconciliation. No live finance, provider messages or marketplace publication occurred; provider sandbox qualification and release approval remain outstanding.

Historical migration tooling

Unreleased migration 536 extends inventory to customers, customer organizations, inactive conversations/tickets, public and private history, tags, declared custom fields, scanned attachments and unpublished internal knowledge. POST /workspaces/{workspaceID}/imports creates a versioned stackshift.support.import/v1 package with a stable Idempotency-Key; reads expose mapping, item warnings, source records while retained, and reconciliation. Existing bulk-data authority and target inbox scope are checked on every operation and worker item. PUT /imports/{importID}/mapping selects existing brand/inbox, published ticket type and knowledge centre/collection. POST /dry-run binds the current revision; confirmed /transitions run starts the existing worker, cancel stops subsequent items, and resume rechecks authority and retained source data. Stable workspace/environment/source-namespace/type/ID receipts prevent overwrites, including changed destinations. Source timestamps remain separate from import time. Historical authors never acquire staff privileges, and no customer notification, outbound message or live automation is emitted. POST /imports/parse accepts bounded portable CSV/versioned JSON and documented Zendesk, Intercom or Freshdesk authorized export snapshot envelopes. Unknown credentials/roles are excluded, unsupported or inaccessible data is reported, public/private distinctions are preserved, and provider URLs are never fetched. Scanned attachment IDs must come from the controlled staff upload path. CSV templates and snapshot shapes are documented in docs/support/historical-imports.md and examples/support/imports. Authorized provider account exports remain unqualified. Erasure scrubs identifying historical content and raw packages sharing the customer source namespace, cancels active work and queues related objects for durable deletion. Configured execution retention scrubs finished raw inventory but retains deduplication evidence. Erased or expired packages cannot restore data through resume. Rollback refuses imported receipts without explicit provenance preservation. PostgreSQL 16 race tests cover cancellation/resume, no overwrite, private notes, tickets/tags, scanned attachments, unpublished knowledge and erasure.

Community discussions

Unreleased migration 537 adds one community per environment/brand, categories, plain-text topics/replies, accepted answers, scanned attachments, subscriptions, metadata-only in-app notifications, search and UUID cursor pagination. configuration:write manages configuration; explicit community:moderate controls moderation and staff reads. Organization membership adds no content access. Portal reads allow anonymous access only for public categories. Customer/group restrictions are checked before detail, search, counts, attachments and notifications. Verified brand-bound portal sessions and CSRF are required to post; erased/blocked/suspended participants cannot write. Bodies and attachments are bounded, and serialized per-customer posting limits apply. Clients must render plain text through text nodes. Reports feed a paginated moderation queue; revision-bound hide/restore, lock/archive and participant suspension are audited. Topic authors or authorized moderators select visible accepted answers. Explicit escalation also requires ticket:write, an authorized inbox/published customer ticket type and an Idempotency-Key; it copies only the visible topic and selected visible replies. Internal ticket updates never flow back to the community. Erasure removes authored identifiers/text and queues owned objects for durable deletion. Actual PostgreSQL 16 race tests and authenticated portal HTTP checks cover visibility/revocation, CSRF, accepted answers, scanned attachments, moderation, escalation replay and privacy erasure. No community UI or live rollout is included. Detailed routes and limits are in docs/support/community.md and the OpenAPI contract. Unreleased migration 538 adds developer-owned registrations and immutable stackshift.support.app/v1 manifests. Private apps require current organization configuration and matching attached workspace access. Owners submit versions; existing platform-admin authorization with a current verified session governs review, approval, suspension and revocation. Support admin roles cannot approve apps. The approved catalog omits private review reasons. Installation requires current integration:write, one authorized inbox, an approved version, an explicit permission subset and renewed consent. The bounded external profile reuses existing machine conversation/message/event/ticket scopes and signed metadata webhooks; it grants no financial, ownership, billing or arbitrary code/proxy authority. Install and upgrade return freshly rotated machine/signing secrets once; normal reads omit them. Old credential bindings remain denied after upgrade, even if manually reactivated. Machine requests and delayed delivery recheck current installer session, SSO/IP, private organization membership, exact manifest consent, scopes and inbox grants. Session expiry/revocation stops execution until an authorized fresh-consent operation. Review suspension/revocation and uninstall disable bound credentials; reapproval does not silently resume them. Test webhook queueing is restricted to test environments and the exact installation revision, with delayed requester revalidation. Local PostgreSQL 16 race and real platform-admin HTTP tests cover consent, review isolation, private catalog scope, signed metadata, upgrade tombstones, suspension and uninstall. examples/support/developer-apps contains a fixed manifest and raw-body HMAC verifier. Applications must enforce timestamp freshness and durable event deduplication; delivery is at least once. Public marketplace publication, external developer servers and provider reviews remain unqualified; no UI or paid settlement is included.

Customer AI replies and connector actions

Unreleased: migration 541, API and Support frontend. In AI workspace → Settings, configure the existing managed provider/token budget or BYOK model/key, enable automatic customer replies, and select inboxes and reply language. Optional handover destinations must use the same brand. Defaults remain off. Only new customer messages in open, unassigned conversations are eligible; historical imports do not start replies. Replies use current customer-visible published knowledge and a restricted projection of successful customer-linked tool results. Private staff notes are excluded. Inherited visibility, verified customer groups, publication schedules, tenant scope, newer messages and changed settings are checked again before sending. Insufficient evidence leads to staff handover. Staff replies pause AI; AI workspace → Conversations lets authorized staff take over or resume for future messages without resending old answers. Allow selected connector actions only for existing connected business tools. Verified customer-linked reads may run automatically. CRM writes, issue creation, escalations and issue reads require review in AI workspace → Action review. Review the exact proposed record, values and selected customer message before approving. Refunds additionally require another authorized staff member. Existing provider credentials, permissions and native receipts are reused; there is no arbitrary URL, shell or database execution. Proposals expire after one hour. Changed policy, revoked consent, rotated connections, changed customer links, erased contacts and human takeover prevent obsolete dispatch. Waiting work releases its inference slot and resumes only from a successful receipt. Failed, declined, expired or uncertain actions hand over. Unknown external writes are not automatically resubmitted; use the existing receipt and reconciliation workflow. Cancellation cannot reverse a completed external action. Turns are bounded to four model steps, one tool call per step and two minutes per inference. Duplicate admission and committed replies are deduplicated across API replicas. Known provider usage remains counted even when a reply is rejected; interrupted dispatched requests conservatively retain their reservation. Proposal/result content follows retention and erasure. AI replies do not count as staff first responses, and a successful reply alone is not a confirmed resolution. Deploy the API with migration 541, then deploy Support hosting. No new environment variable or separate platform-worker/node-agent release is required solely for this feature. Existing provider and language evaluation requirements remain distinct from availability. The API contract and operator guidance are in openapi/support-v1.openapi.yaml and docs/support/customer-ai.md.

Backend release preparation

The next API release retries only database-confirmed serialization/deadlock aborts during widget session creation, preserving admission limits without replaying unknown commit outcomes. Cross-replica integration checks cover conversation idempotency and logout revocation. Transcription availability now reflects workspace opt-in, managed or BYOK credentials, object storage and monthly allowance; missing prerequisites reject before quota reservation. Availability is distinct from provider/language qualification. The unreleased ./deploy.sh support target packages the dashboard, portal and messenger in a non-root, read-only container with health checks and a verified image digest. It is opt-in and does not launch during unrelated API/worker releases. Portal and dashboard API calls stay same-origin; the embedded messenger uses the configured public API origin. The Support release creates a missing dashboard DNS record only after container health passes and verifies configured Cloudflare portal fallback routing; conflicting records are preserved. Custom portal origin certificates require an ownership-verified provider binding. Serving customer traffic additionally requires an active domain and workspace, and removed domains are denied even when a certificate remains cached. Customer hosts expose only portal routes, while Mail tracking keeps its existing private certificate endpoint for rollout compatibility. Deploy the API before Support hosting, then verify public HTTPS and an authorized portal journey. Operator documentation and runtime/test names use domain names rather than numbered phases. Integration runners use SUPPORT_TEST_DATABASE_URL and SUPPORT_TEST_PG_DUMP; retention metrics use analytics_retention and recovery metadata uses support-recovery-v1. Backend release preparation is unreleased and is not launch approval. Production inspection found schema 526 and no Support environment variables in the running API. The coordinated release requires migrations 527–541; the complete catalog through 540 now applies on a disposable PostgreSQL 16 database. No production migration or deployment was performed. The workspace-root deploy.sh and deployments/docker-compose.platform.yml are authoritative. Both API slots now receive Support configuration. Before migrations, a secret-safe check validates enabled configuration, matching slot settings, HTTPS origins, encryption/signing key lengths, provider credential groups and bounded limits. Disabled Support remains allowed for unrelated releases but is not a readiness pass. Missing or unsafe enabled settings block release instead of silently disabling functionality. SLA clocks capture optional response and handoff durations, approaching thresholds and escalation actions with the policy revision. Editing a policy preserves existing clocks; explicit reapplication adopts current settings. Migration 539 backfills only matching historical revisions. Unrecoverable older settings stay unknown while existing deadlines remain intact; optional targets require explicit reapplication rather than silently using a newer policy. Support jobs run inside enabled API processes. The private metrics endpoint now exposes bounded worker operation outcomes/durations and completed sweep timestamps; the observability installer includes stalled-worker and sustained-error alerts. Empty polls are not deliveries, and a completed sweep does not prove provider success. API images include the operator-only Support recovery command; it never runs automatically. Operator smoke/load scripts accept test installations only, refuse live keys, bound network calls and end successful sessions. They do not establish capacity or authorize real charges, refunds or customer messages. The production Paystack key must not be used for qualification. Support subscriptions reuse the platform gateway policy and existing credentials. Merchant-connected integrations remain isolated because they belong to each customer, not StackShift. The unreleased shared-billing update routes Support checkout through the same Bachs-first policy as platform billing, retaining the chosen gateway and currency on every order. Migration 540 preserves existing NGN/Paystack records and adds optional USD prices to administrator catalogs; zero USD disables that currency. Checkout defaults to NGN and supports USD when priced. The legacy amount_kobo response contains minor units of its returned currency. Existing payment pages are reused; uncertain initialization and interrupted renewals reconcile without repeating charges. Successful payment and charge webhooks only wake gateway verification. Manual subscriptions suspend at period end; automatic renewal requires consent and reusable gateway authorization. Refund/dispute entitlement adjustments remain operator-managed. Enabling checkout does not publish prices or grant allowances. Core activation and new-message admission are separate from paid checkout, which can remain disabled. Dashboard availability requires working hosting and TLS. Enterprise IP restrictions, custom portal domains and external providers require their own trusted-proxy, Cloudflare and sandbox qualification. Deployed-path and load verification and a current restore including Support attachment/export objects and deletion/revocation replay remain operational checks. Database backups alone do not cover those objects. The next release implements customer replies and governed AI connector actions with migration 541 and API/Support frontend updates; live provider and language qualification remain separate. Frontend approval is separate. The unreleased article translation endpoint POST /api/v1/support/workspaces/{workspaceID}/ai/article-translations accepts environment_id, article_id, current article source_revision, source_locale and target_locale with an Idempotency-Key. It requires current knowledge author/team access, knowledge AI opt-in and provider budget. It returns a stored draft with translated title, summary and content while preserving document structure, links, code and attachments. Staff review and save through the existing knowledge translation workflow; nothing is automatically published. Source edits, revocation and cancellation are checked. Inputs are bounded to 12,000 characters and 256 text segments, with two-minute durable execution. HTTP disconnect only stops waiting. Unknown provider outcomes retain conservative budget and are never automatically repeated. Migrations 549–553 add author batches, immutable approved glossaries, cost reporting, bounded replay, evaluation and explicit handling focus; see Support AI, media and handling reporting. The operator handoff and evidence ledger are docs/support/release-readiness.md and docs/support/release-verification.md in the backend repository. No numerical recovery objective, supported residency region, provider approval or deployment is inferred from local tests.

Qualification

Local signed-session HTTP and real PostgreSQL tests cover organization membership, invitations, attachment, audit pagination and custom-role isolation, lifecycle, assignment revisions and guarded detach. The installed PostgreSQL 14 test baseline applies unchanged Support migrations 474, 475, 527, 528 and 529; Disposable PostgreSQL 16.15 now applies unchanged Support prerequisites 474–490 and Phase 10 migrations; disposable full Support database/object restore and tombstone reapplication pass locally; deployed backup/index/provider coverage remains unqualified. Organization audit entries record actor, action, target and time without invitation tokens or message bodies. They are application audit records, not an immutability or compliance certification.

Expected result

Workspace IDs, customer records, environment boundaries and billing remain unchanged. Explicit workspace membership and inbox grants continue to control Support content.

Common failures

  • Organization administrators without a workspace membership receive not_found on workspace content routes.
  • Attachment returns stale_revision if the workspace or request changed after organization approval. Cancel the obsolete request and request a new attachment.
  • Invitation acceptance rejects unverified accounts, other accounts, expired or revoked tokens, token reuse, and revoked inviter authority.
  • Custom roles cannot receive ownership, billing, workspace deletion or whole-workspace archive permissions. Those operations retain their built-in role requirements.