{"record":{"id":"d799468a993eacb5","repo":"bitwarden/server","slug":"you-do-not-have-permission-to-create-a-connection","errorCode":null,"errorMessage":"You do not have permission to create a connection of type {model.Type}.","messagePattern":"You do not have permission to create a connection of type (.+?)\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/AdminConsole/Controllers/OrganizationConnectionsController.cs","lineNumber":59,"sourceCode":"        _deleteOrganizationConnectionCommand = deleteOrganizationConnectionCommand;\n        _organizationConnectionRepository = organizationConnectionRepository;\n        _currentContext = currentContext;\n        _globalSettings = globalSettings;\n        _licensingService = licensingService;\n    }\n\n    [HttpGet(\"enabled\")]\n    public bool ConnectionsEnabled()\n    {\n        return _globalSettings.SelfHosted && _globalSettings.EnableCloudCommunication;\n    }\n\n    [HttpPost]\n    public async Task<OrganizationConnectionResponseModel> CreateConnection([FromBody] OrganizationConnectionRequestModel model)\n    {\n        if (!await HasPermissionAsync(model.OrganizationId, model.Type))\n        {\n            throw new BadRequestException($\"You do not have permission to create a connection of type {model.Type}.\");\n        }\n\n        if (await HasConnectionTypeAsync(model, null, model.Type))\n        {\n            throw new BadRequestException($\"The requested organization already has a connection of type {model.Type}. Only one of each connection type may exist per organization.\");\n        }\n\n        switch (model.Type)\n        {\n            case OrganizationConnectionType.CloudBillingSync:\n                return await CreateOrUpdateOrganizationConnectionAsync<BillingSyncConfig>(null, model, ValidateBillingSyncConfig);\n            case OrganizationConnectionType.Scim:\n                return await CreateOrUpdateOrganizationConnectionAsync<ScimConfig>(null, model);\n            default:\n                throw new BadRequestException($\"Unknown Organization connection Type: {model.Type}\");\n        }\n    }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/AdminConsole/Controllers/OrganizationConnectionsController.cs#L41-L77","documentation":"Thrown by OrganizationConnectionsController.CreateConnection (POST /organizations/connections) when HasPermissionAsync returns false. Permission is type-dependent: Scim connections require the ManageScim claim, while all other types (default branch) require OrganizationOwner. The check also returns false when model.OrganizationId is null/empty, so a missing or zero Guid fails here before the type-specific claim is even evaluated. Maps to HTTP 400 via BadRequestException.","triggerScenarios":"POST /organizations/connections where the authenticated user lacks the claim for the requested type: a non-owner calling with type=CloudBillingSync, a user without ManageScim calling with type=Scim, or any request where model.OrganizationId is Guid.Empty / omitted (the client sent no organizationId in the JSON body).","commonSituations":"An admin (not owner) trying to set up Cloud Billing Sync; a custom-scoped API token or service account that was never granted ManageScim; a client bug that sends an empty Guid because the org context was never loaded; testing against a freshly provisioned org where the calling user has not yet been promoted to owner.","solutions":["Verify the calling user's role: CloudBillingSync requires Organization Owner, Scim requires the ManageScim permission — promote the user or use an account that already holds the claim.","Ensure model.OrganizationId is a real, non-empty Guid in the request body (not Guid.Empty and not omitted).","Confirm the request carries the correct authentication token for the intended organization user (not a personal account lacking org membership).","If using an API key / service account, grant it the necessary organization-scoped permissions before retrying."],"exampleFix":"// before\nvar model = new OrganizationConnectionRequestModel {\n    Type = OrganizationConnectionType.CloudBillingSync,\n    OrganizationId = Guid.Empty  // fails permission check\n};\n// after\nvar model = new OrganizationConnectionRequestModel {\n    Type = OrganizationConnectionType.CloudBillingSync,\n    OrganizationId = fetchedOrgId  // real Guid, caller is an Owner of this org\n};","handlingStrategy":"validation","validationCode":"// Before POST, ensure the caller holds the right claim and a valid org id\nif (model.OrganizationId == Guid.Empty) throw new ArgumentException(\"OrganizationId required\");\nvar needsOwner = model.Type != OrganizationConnectionType.Scim;\nvar canManage = needsOwner\n    ? await currentUser.IsOrganizationOwnerAsync(model.OrganizationId)\n    : await currentUser.CanManageScimAsync(model.OrganizationId);\nif (!canManage) throw new UnauthorizedAccessException(\"Caller lacks permission for this connection type\");","typeGuard":"static bool CanCreateConnection(OrganizationConnectionType t) =>\n    t is OrganizationConnectionType.CloudBillingSync or OrganizationConnectionType.Scim;","tryCatchPattern":null,"preventionTips":["Resolve the caller's org role from a trusted source (not the request body) before calling the API.","Never send Guid.Empty as OrganizationId — load it from the org context.","For Scim, confirm ManageScim is granted; for CloudBillingSync, confirm Owner."],"tags":["permissions","organization-connections","authorization","http-400"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}