{"record":{"id":"f4f07a08d9a056bb","repo":"RocketChat/Rocket.Chat","slug":"error-abac-attribute-store-external","errorCode":"error-abac-attribute-store-external","errorMessage":"error-abac-attribute-store-external","messagePattern":"error-abac-attribute-store-external","errorType":"error_code","errorClass":"AbacAttributeStoreExternalError","httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/abac/index.ts","lineNumber":45,"sourceCode":"\tGETAbacPdpHealthErrorResponseSchema,\n} from './schemas';\nimport { API } from '../../../../server/api';\nimport type { ExtractRoutesFromAPI } from '../../../../server/api/ApiClass';\nimport { getPaginationItems } from '../../../../server/api/lib/getPaginationItems';\nimport { settings } from '../../../../server/settings';\n\nconst getActorFromUser = (user?: IUser | null): AbacActor | undefined =>\n\tuser?._id\n\t\t? {\n\t\t\t\t_id: user._id,\n\t\t\t\tusername: user.username,\n\t\t\t\tname: user.name,\n\t\t\t}\n\t\t: undefined;\n\nconst assertLocalAttributeStore = async (): Promise<void> => {\n\tif (await Abac.isExternalAttributeStore()) {\n\t\tthrow new AbacAttributeStoreExternalError();\n\t}\n};\n\nconst abacEndpoints = API.v1\n\t.post(\n\t\t'abac/rooms/:rid/attributes',\n\t\t{\n\t\t\tauthRequired: true,\n\t\t\tpermissionsRequired: ['abac-management', 'manage-abac-admin-rooms'],\n\t\t\tbody: POSTRoomAbacAttributesBodySchema,\n\t\t\tresponse: {\n\t\t\t\t200: GenericSuccessSchema,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t\t400: GenericErrorSchema,\n\t\t\t\t403: validateUnauthorizedErrorResponse,\n\t\t\t},\n\t\t\tlicense: ['abac'],\n\t\t},","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/abac/index.ts#L27-L63","documentation":"AbacAttributeStoreExternalError (`error-abac-attribute-store-external`) thrown by assertLocalAttributeStore in the EE ABAC REST endpoints. Attribute-definition write endpoints (POST/PUT abac/attributes...) manage Rocket.Chat's local attribute store; when the deployment sources attributes from an external store (Abac.isExternalAttributeStore() resolves true, e.g. attributes synced from LDAP), local CRUD is rejected.","triggerScenarios":"Calling POST /v1/abac/attributes or PUT /v1/abac/attributes/:_id on a workspace whose ABAC attributes are provided by an external identity store; adding the guard after configuring LDAP-backed attributes.","commonSituations":"Admins scripting attribute definitions against an LDAP-integrated workspace; migration tooling replaying local-store payloads on an externally-backed deployment.","solutions":["Manage attributes in the external store (e.g. the LDAP directory attributes mapped in settings) instead of the local ABAC API.","If local storage is intended, remove/reconfigure the external attribute source so isExternalAttributeStore() returns false.","Make provisioning scripts skip these endpoints when an external store is configured."],"exampleFix":"// before\nawait POST('abac/attributes', definition); // 400 error-abac-attribute-store-external\n\n// after\nif (await Abac.isExternalAttributeStore()) {\n\tthrow new Error('Manage attributes in the external (LDAP) store');\n}\nawait POST('abac/attributes', definition);","handlingStrategy":"validation","validationCode":"const isLocalAttributeStore = async (): Promise<boolean> => !(await Abac.isExternalAttributeStore());\n\n// guard before calling local attribute-definition endpoints\nif (!(await isLocalAttributeStore())) throw new Error('Attributes are managed externally');","typeGuard":"const isExternalStoreError = (error: unknown): boolean =>\n\tBoolean(error && typeof error === 'object' && 'error' in error && (error as { error: string }).error === 'error-abac-attribute-store-external');","tryCatchPattern":"try {\n\tawait POST('abac/attributes', definition);\n} catch (error) {\n\tif (isExternalStoreError(error)) {\n\t\t// route to the external (LDAP) attribute source; never retry locally\n\t\tthrow new Error('Manage ABAC attributes in the external store');\n\t}\n\tthrow error;\n}","preventionTips":["Detect the store mode (Abac.isExternalAttributeStore) before any local attribute CRUD.","Point attribute provisioning at the LDAP directory when attributes are externally sourced.","Document store mode per environment so scripts target the right surface."],"tags":["ee","abac","rest-api","external-store"],"backgroundTag":"external-store-read-only","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}