{
  "schemaVersion": "1.0",
  "title": "Authenticate and isolate a Twenty workspace",
  "description": "Use this guide to bind one standalone Twenty host to one verified AIP tenant, one fixed provider origin, and one Twenty workspace. The API token stays in an owner-controlled file and is added to provider requests inside the connector.",
  "canonical": "https://getaip.org/docs/connectors/twenty/getting-started/authentication-and-workspace-isolation",
  "route": "/docs/connectors/twenty/getting-started/authentication-and-workspace-isolation",
  "source": "docs/connectors/twenty/getting-started/authentication-and-workspace-isolation.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/twenty/getting-started/authentication-and-workspace-isolation.md",
    "txt": "/docs/download/connectors/twenty/getting-started/authentication-and-workspace-isolation.txt",
    "json": "/docs/download/connectors/twenty/getting-started/authentication-and-workspace-isolation.json",
    "pdf": "/docs/download/connectors/twenty/getting-started/authentication-and-workspace-isolation.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Authenticate and isolate a Twenty workspace\ndescription: >-\n  Bind one verified AIP tenant to one fixed Twenty workspace and owner-held\n  provider credentials\nkind: how-to\naudience: operator\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: twenty\naliases:\n  - Twenty authentication\n  - Twenty workspace isolation\n  - Twenty API token\n---\n\n# Authenticate and isolate a Twenty workspace\n\nUse this guide to bind one standalone Twenty host to one verified AIP tenant,\none fixed provider origin, and one Twenty workspace. The API token stays in an\nowner-controlled file and is added to provider requests inside the connector.\n\nThe workspace is deployment identity, not Action input. A caller can select an\nadmitted record object or metadata resource, but it cannot select another\norigin, workspace, API token, webhook secret, or AIP tenant.\n\n## Keep the credential layers separate\n\nSix values protect different boundaries. Do not reuse one value for another\nlayer.\n\n| Layer | Protects | Secret |\n|---|---|---|\n| Caller credential | Application to `aipd` | Yes |\n| Gateway signature | `aipd` to the connector host | The gateway signing key is secret |\n| Host credential revision | Route authorization before provider work | No provider secret bytes |\n| Twenty API token | Connector host to the fixed workspace | Yes |\n| Twenty webhook HMAC secret | Provider ingress to the host | Yes, and separate from the API token |\n| Host signing seed | Connector host responses and callbacks | Yes |\n\nAn AIP native bearer-token file authenticates a caller to `aipd`. It must not\npoint to the Twenty API-token file. Credential revision metadata can fence an\nadmitted route, but it does not contain or replace the provider token.\n\n## Prerequisites\n\nBefore changing the binding, require:\n\n- one admitted Twenty connector version and instance;\n- one verified AIP tenant and membership;\n- one stable Twenty origin and RFC 4122 workspace UUID;\n- one provider token limited to the admitted operation set;\n- owner-controlled mounts for every secret file;\n- exact host, gateway, control-plane, artifact, and registry identities;\n- a rollback window in which the old replica and credential remain valid.\n\nRecord source revision, image digest, connector version, instance, replica,\ntenant, external account, workspace, and credential revision. Do not record\nsecret values.\n\n## 1. Provision the provider token file\n\nCreate the token through the deployment's secret manager and mount it as a\nregular owner-controlled file. On Unix, any group or world permission bit\ncauses the common secret reader to reject the file.\n\nA representative permission shape is:\n\n```text\n-rw------- 1 <host-uid> <host-gid> ... /run/secrets/twenty-api-token\n```\n\nThe file must contain one non-empty UTF-8 value after surrounding ASCII\nwhitespace is removed. The Twenty host reads at most 16 KiB. The common reader\nrejects a symlink, non-regular file, replacement race, empty file, or oversized\nfile and zeroizes its temporary string.\n\nDo not place the token in:\n\n- an Action, manifest, registry row, capability input, or admission package;\n- a command-line argument or ordinary environment variable;\n- a base URL, image layer, Compose file, log, or evidence bundle;\n- the non-secret credential ID, issuer, revision, or provider reference;\n- the webhook-secret file.\n\n## 2. Configure the fixed provider boundary\n\nConfigure one origin, workspace, and token-file path:\n\n```text\nAIP_TWENTY_BASE_URL=https://crm.example.test\nAIP_TWENTY_WORKSPACE_ID=0190c42f-2d5a-7000-8000-000000000001\nAIP_TWENTY_API_TOKEN_FILE=/run/secrets/twenty-api-token\n```\n\nThe origin must use HTTPS unless it is loopback HTTP or an operator explicitly\npermits HTTP for a trusted private network. It cannot contain a username,\npassword, path prefix, query, or fragment. Provider redirects remain disabled.\n\nThe workspace ID must be a canonical 36-character RFC 4122 UUID with version\n1 through 5 and an RFC variant nibble. The connector uses this UUID for record\nidentity derivation and signed webhook workspace comparison.\n\nThe connector applies the provider token as an HTTP `Bearer` credential. The\norigin, workspace, and token are fixed when the host process starts.\n\n## 3. Bind the host to the tenant and external account\n\nConfigure fleet identity separately from the provider credential:\n\n```text\nAIP_CONNECTOR_HOST_TENANT_ID=tenant-crm-production\nAIP_CONNECTOR_HOST_MEMBERSHIP_ID=membership-twenty-primary\nAIP_CONNECTOR_HOST_EXTERNAL_ACCOUNT_ID=0190c42f-2d5a-7000-8000-000000000001\nAIP_CONNECTOR_HOST_EXTERNAL_ACCOUNT_SYSTEM=twenty\nAIP_CONNECTOR_HOST_SECRET_PROVIDER_REF=secret://production/twenty/primary\n```\n\nExternal-account ID and system must be present together or both absent. For a\ntenant-owned workspace, set both and require the external-account ID to equal\n`AIP_TWENTY_WORKSPACE_ID` through deployment policy.\n\nThe reviewed host validates the two settings independently. It does not compare\nexternal-account ID with the Twenty workspace automatically. Admission review\nand deployment validation must detect a mismatch before routing is enabled.\n\nDiscovery uses the verified AIP tenant as the manifest namespace when one is\npresent. The provider workspace remains the connector's fixed account boundary.\nThese identifiers serve different roles and need not use the same syntax.\n\nThe registry binding must associate only the intended tenant and admitted\nTwenty capabilities with this instance. A signed Action cannot override the\nverified tenant or redirect the host to another workspace.\n\n## 4. Configure credential identity and revision fencing\n\nThe common host can attach a non-secret credential handle to its verified\nexecution context. Configure all handle fields together:\n\n```text\nAIP_CONNECTOR_HOST_CREDENTIAL_ID=twenty-primary-provider\nAIP_CONNECTOR_HOST_CREDENTIAL_ISSUER=twenty-deployment\nAIP_CONNECTOR_HOST_CREDENTIAL_SCOPES=twenty:record.list,twenty:record.create\nAIP_CONNECTOR_HOST_CREDENTIAL_REVISION=twenty-primary-2026-07-27-01\nAIP_CONNECTOR_HOST_CREDENTIAL_POLICY_FILE=/run/config/twenty-credential-policy.json\n```\n\nID, issuer, revision, and at least one non-empty scope form one handle. Partial\nconfiguration fails startup. Use scopes derived from the admitted operation\nset rather than a wildcard copied from a controlled fixture.\n\nThe reloadable policy can deny the configured or pinned revision before a\nprovider side effect. An unreadable, invalid, or non-authorizing policy fails\nclosed. This mechanism does not hot-reload the provider token file.\n\n## 5. Keep webhook credentials independent\n\nConfigure webhook ingress only when the deployment needs it:\n\n```text\nAIP_TWENTY_WEBHOOK_SECRET_FILE=/run/secrets/twenty-webhook-hmac\nAIP_CONNECTOR_HOST_EVENT_ENDPOINT=https://aipd.example.test/aip/v1/events\n```\n\nThe webhook secret uses the same bounded secret-file reader as the API token,\nbut it has a different purpose and value. Omission disables the Twenty webhook\nroute. Supplying the secret without a central event endpoint fails startup.\n\nThe connector accepts a signed webhook only when the payload `workspaceId`\nequals `AIP_TWENTY_WORKSPACE_ID`. HMAC validity cannot authorize an event from\nanother configured workspace.\n\nMetadata Actions cannot provide a webhook `secret`. Create injects the\nhost-owned configured secret, update injects it only for an explicit rotation\nrequest, and connector results recursively remove secret fields.\n\n## 6. Verify isolation before enabling mutations\n\nKeep new mutation bindings disabled while admitting and checking the host.\nVerify in this order:\n\n1. the host registers with the expected connector type, version, instance,\n   replica, artifact digest, tenant, and external account;\n2. authenticated health reaches the fixed workspace without printing the token;\n3. discovery for the intended tenant exposes only the admitted operations;\n4. a bounded `record.list` completes through the signed gateway path;\n5. the result belongs to the intended workspace and object;\n6. an unauthorized tenant has no eligible Twenty route;\n7. an Action cannot provide origin, workspace, or credential material;\n8. a revoked credential revision is denied before provider work;\n9. a webhook from a different workspace fails even with valid field shapes.\n\nUse a read before any provider mutation. If returned data belongs to another\nworkspace, disable the binding and reconcile workspace, external-account,\ncredential, and registry identities.\n\n## 7. Rotate the provider token\n\nThe Twenty token is read when the host starts. Replacing the mounted file under\na running process is not a documented token reload.\n\nRotate with a bounded replica rollout:\n\n1. create a least-privilege replacement token for the same workspace;\n2. mount it at a new owner-controlled path without changing the old replica;\n3. allocate a new credential revision and host configuration revision;\n4. update revision policy and admission material through controlled paths;\n5. start a replacement replica with the new token file;\n6. verify authenticated health, a bounded read, and unauthorized-tenant isolation;\n7. route new assignments to the replacement and drain the old replica;\n8. revoke the old token after in-flight work and rollback needs settle;\n9. retain identities, checks, drain state, and revocation evidence without token bytes.\n\nUse a separate controlled procedure for webhook-secret rotation. Provider\nwebhook configuration and host secret rollout must overlap without exposing the\nsecret in Action input or evidence.\n\n## Resolve authentication and isolation failures\n\n| Symptom | Decision |\n|---|---|\n| Token file is rejected | Check file type, ownership, mode, UTF-8 content, and 16 KiB bound without printing it |\n| Provider origin is rejected | Use an allowed origin with no credentials, path, query, or fragment |\n| Workspace ID is rejected | Supply an RFC 4122 UUID version 1 through 5 in canonical form |\n| External-account configuration is rejected | Set ID and system together, then compare the ID with the workspace UUID |\n| Credential handle is rejected | Configure ID, issuer, revision, and non-empty scopes together |\n| Revision policy denies the route | Keep mutations disabled and repair policy or the pinned revision |\n| Host registers but discovery is empty | Compare tenant, membership, operation allowlist, admission, and route policy |\n| Provider returns `401` or `403` | Check token ownership, expiry, permissions, origin, and workspace; do not retry a mutation |\n| Provider returns a redirect | Correct the fixed origin or provider routing; credentials are not forwarded |\n| Webhook workspace differs | Reject the event and reconcile provider webhook ownership with the host binding |\n\n## Related documentation\n\n- [Twenty connector overview](../README.md)\n- [Twenty connector quickstart](quickstart.md)\n- [Rotate connector credentials](../../../guides/connector-credentials-and-rotation.md)\n- [Connector registry and routing](../../../architecture/connector-registry-and-routing.md)\n- [Security model](../../../architecture/security-model.md)\n",
    "text": "Authenticate and isolate a Twenty workspace\n\nUse this guide to bind one standalone Twenty host to one verified AIP tenant,\none fixed provider origin, and one Twenty workspace. The API token stays in an\nowner-controlled file and is added to provider requests inside the connector.\n\nThe workspace is deployment identity, not Action input. A caller can select an\nadmitted record object or metadata resource, but it cannot select another\norigin, workspace, API token, webhook secret, or AIP tenant.\n\nKeep the credential layers separate\n\nSix values protect different boundaries. Do not reuse one value for another\nlayer.\n\n| Layer | Protects | Secret |\n\n| Caller credential | Application to aipd | Yes |\n| Gateway signature | aipd to the connector host | The gateway signing key is secret |\n| Host credential revision | Route authorization before provider work | No provider secret bytes |\n| Twenty API token | Connector host to the fixed workspace | Yes |\n| Twenty webhook HMAC secret | Provider ingress to the host | Yes, and separate from the API token |\n| Host signing seed | Connector host responses and callbacks | Yes |\n\nAn AIP native bearer-token file authenticates a caller to aipd. It must not\npoint to the Twenty API-token file. Credential revision metadata can fence an\nadmitted route, but it does not contain or replace the provider token.\n\nPrerequisites\n\nBefore changing the binding, require:\n• one admitted Twenty connector version and instance;\n• one verified AIP tenant and membership;\n• one stable Twenty origin and RFC 4122 workspace UUID;\n• one provider token limited to the admitted operation set;\n• owner-controlled mounts for every secret file;\n• exact host, gateway, control-plane, artifact, and registry identities;\n• a rollback window in which the old replica and credential remain valid.\n\nRecord source revision, image digest, connector version, instance, replica,\ntenant, external account, workspace, and credential revision. Do not record\nsecret values.\n1. Provision the provider token file\n\nCreate the token through the deployment's secret manager and mount it as a\nregular owner-controlled file. On Unix, any group or world permission bit\ncauses the common secret reader to reject the file.\n\nA representative permission shape is:\n\n-rw------- 1   ... /run/secrets/twenty-api-token\n\nThe file must contain one non-empty UTF-8 value after surrounding ASCII\nwhitespace is removed. The Twenty host reads at most 16 KiB. The common reader\nrejects a symlink, non-regular file, replacement race, empty file, or oversized\nfile and zeroizes its temporary string.\n\nDo not place the token in:\n• an Action, manifest, registry row, capability input, or admission package;\n• a command-line argument or ordinary environment variable;\n• a base URL, image layer, Compose file, log, or evidence bundle;\n• the non-secret credential ID, issuer, revision, or provider reference;\n• the webhook-secret file.\n2. Configure the fixed provider boundary\n\nConfigure one origin, workspace, and token-file path:\n\nAIPTWENTYBASEURL=https://crm.example.test\nAIPTWENTYWORKSPACEID=0190c42f-2d5a-7000-8000-000000000001\nAIPTWENTYAPITOKENFILE=/run/secrets/twenty-api-token\n\nThe origin must use HTTPS unless it is loopback HTTP or an operator explicitly\npermits HTTP for a trusted private network. It cannot contain a username,\npassword, path prefix, query, or fragment. Provider redirects remain disabled.\n\nThe workspace ID must be a canonical 36-character RFC 4122 UUID with version\n1 through 5 and an RFC variant nibble. The connector uses this UUID for record\nidentity derivation and signed webhook workspace comparison.\n\nThe connector applies the provider token as an HTTP Bearer credential. The\norigin, workspace, and token are fixed when the host process starts.\n3. Bind the host to the tenant and external account\n\nConfigure fleet identity separately from the provider credential:\n\nAIPCONNECTORHOSTTENANTID=tenant-crm-production\nAIPCONNECTORHOSTMEMBERSHIPID=membership-twenty-primary\nAIPCONNECTORHOSTEXTERNALACCOUNTID=0190c42f-2d5a-7000-8000-000000000001\nAIPCONNECTORHOSTEXTERNALACCOUNTSYSTEM=twenty\nAIPCONNECTORHOSTSECRETPROVIDERREF=secret://production/twenty/primary\n\nExternal-account ID and system must be present together or both absent. For a\ntenant-owned workspace, set both and require the external-account ID to equal\nAIPTWENTYWORKSPACEID through deployment policy.\n\nThe reviewed host validates the two settings independently. It does not compare\nexternal-account ID with the Twenty workspace automatically. Admission review\nand deployment validation must detect a mismatch before routing is enabled.\n\nDiscovery uses the verified AIP tenant as the manifest namespace when one is\npresent. The provider workspace remains the connector's fixed account boundary.\nThese identifiers serve different roles and need not use the same syntax.\n\nThe registry binding must associate only the intended tenant and admitted\nTwenty capabilities with this instance. A signed Action cannot override the\nverified tenant or redirect the host to another workspace.\n4. Configure credential identity and revision fencing\n\nThe common host can attach a non-secret credential handle to its verified\nexecution context. Configure all handle fields together:\n\nAIPCONNECTORHOSTCREDENTIALID=twenty-primary-provider\nAIPCONNECTORHOSTCREDENTIALISSUER=twenty-deployment\nAIPCONNECTORHOSTCREDENTIALSCOPES=twenty:record.list,twenty:record.create\nAIPCONNECTORHOSTCREDENTIALREVISION=twenty-primary-2026-07-27-01\nAIPCONNECTORHOSTCREDENTIALPOLICYFILE=/run/config/twenty-credential-policy.json\n\nID, issuer, revision, and at least one non-empty scope form one handle. Partial\nconfiguration fails startup. Use scopes derived from the admitted operation\nset rather than a wildcard copied from a controlled fixture.\n\nThe reloadable policy can deny the configured or pinned revision before a\nprovider side effect. An unreadable, invalid, or non-authorizing policy fails\nclosed. This mechanism does not hot-reload the provider token file.\n5. Keep webhook credentials independent\n\nConfigure webhook ingress only when the deployment needs it:\n\nAIPTWENTYWEBHOOKSECRETFILE=/run/secrets/twenty-webhook-hmac\nAIPCONNECTORHOSTEVENTENDPOINT=https://aipd.example.test/aip/v1/events\n\nThe webhook secret uses the same bounded secret-file reader as the API token,\nbut it has a different purpose and value. Omission disables the Twenty webhook\nroute. Supplying the secret without a central event endpoint fails startup.\n\nThe connector accepts a signed webhook only when the payload workspaceId\nequals AIPTWENTYWORKSPACEID. HMAC validity cannot authorize an event from\nanother configured workspace.\n\nMetadata Actions cannot provide a webhook secret. Create injects the\nhost-owned configured secret, update injects it only for an explicit rotation\nrequest, and connector results recursively remove secret fields.\n6. Verify isolation before enabling mutations\n\nKeep new mutation bindings disabled while admitting and checking the host.\nVerify in this order:\n1. the host registers with the expected connector type, version, instance,\n   replica, artifact digest, tenant, and external account;\n2. authenticated health reaches the fixed workspace without printing the token;\n3. discovery for the intended tenant exposes only the admitted operations;\n4. a bounded record.list completes through the signed gateway path;\n5. the result belongs to the intended workspace and object;\n6. an unauthorized tenant has no eligible Twenty route;\n7. an Action cannot provide origin, workspace, or credential material;\n8. a revoked credential revision is denied before provider work;\n9. a webhook from a different workspace fails even with valid field shapes.\n\nUse a read before any provider mutation. If returned data belongs to another\nworkspace, disable the binding and reconcile workspace, external-account,\ncredential, and registry identities.\n7. Rotate the provider token\n\nThe Twenty token is read when the host starts. Replacing the mounted file under\na running process is not a documented token reload.\n\nRotate with a bounded replica rollout:\n1. create a least-privilege replacement token for the same workspace;\n2. mount it at a new owner-controlled path without changing the old replica;\n3. allocate a new credential revision and host configuration revision;\n4. update revision policy and admission material through controlled paths;\n5. start a replacement replica with the new token file;\n6. verify authenticated health, a bounded read, and unauthorized-tenant isolation;\n7. route new assignments to the replacement and drain the old replica;\n8. revoke the old token after in-flight work and rollback needs settle;\n9. retain identities, checks, drain state, and revocation evidence without token bytes.\n\nUse a separate controlled procedure for webhook-secret rotation. Provider\nwebhook configuration and host secret rollout must overlap without exposing the\nsecret in Action input or evidence.\n\nResolve authentication and isolation failures\n\n| Symptom | Decision |\n\n| Token file is rejected | Check file type, ownership, mode, UTF-8 content, and 16 KiB bound without printing it |\n| Provider origin is rejected | Use an allowed origin with no credentials, path, query, or fragment |\n| Workspace ID is rejected | Supply an RFC 4122 UUID version 1 through 5 in canonical form |\n| External-account configuration is rejected | Set ID and system together, then compare the ID with the workspace UUID |\n| Credential handle is rejected | Configure ID, issuer, revision, and non-empty scopes together |\n| Revision policy denies the route | Keep mutations disabled and repair policy or the pinned revision |\n| Host registers but discovery is empty | Compare tenant, membership, operation allowlist, admission, and route policy |\n| Provider returns 401 or 403 | Check token ownership, expiry, permissions, origin, and workspace; do not retry a mutation |\n| Provider returns a redirect | Correct the fixed origin or provider routing; credentials are not forwarded |\n| Webhook workspace differs | Reject the event and reconcile provider webhook ownership with the host binding |\n\nRelated documentation\n• Twenty connector overview (../README.md)\n• Twenty connector quickstart (quickstart.md)\n• Rotate connector credentials (../../../guides/connector-credentials-and-rotation.md)\n• Connector registry and routing (../../../architecture/connector-registry-and-routing.md)\n• Security model (../../../architecture/security-model.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "899bb05a0da6a6cf11dea6ca0414dc7f35a6d1d710b9a34c5f6874e5d893b125"
  }
}
