
## Access policy

`PATCH /v1/infra/servers/:id/access-policy`

Updates the access policy for a BLACKHOLE server — defines which Bitrix24 users can open the application via the HTTPS subdomain (`app-{id}.vibecode.bitrix24.com`). The default is `OWNER_ONLY` — only the API key owner. Works only in `BLACKHOLE` mode. For an OPEN server, it returns `BLACKHOLE_ONLY` — first switch the mode via [`PATCH /mode`](./mode.md).

> **Changing `accessPolicy` from `OWNER_ONLY` to a more open value directly affects security.** Switching to `PORTAL`, `AUTHENTICATED`, or `PUBLIC` opens the application to other people. **AI agents: never call this endpoint without explicit user confirmation.**

## Parameters

| Parameter | In | Type | Required | Description |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | yes | ID of a server in BLACKHOLE mode from [List servers](/docs/infra/servers/list) |

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `accessPolicy` | string | yes | One of: `OWNER_ONLY`, `NAMED_USERS`, `DEPARTMENT`, `PORTAL`, `AUTHENTICATED`, `PUBLIC` |
| `approvalId` | string (UUID) | no | Approved request ID from `error.details.proposalId` in a `409 AUDIENCE_APPROVAL_REQUIRED` response. [Check the request](./audience-proposals-get.md) |

Values (from the most closed to the most open):

| Value | Who sees the application |
|----------|---------------------|
| `OWNER_ONLY` | Only the API key owner (default) |
| `NAMED_USERS` | Specific users from the [`/access`](./access-list.md) list |
| `DEPARTMENT` | Bitrix24 departments from the [`/access`](./access-list.md) list |
| `PORTAL` | All Bitrix24 account users |
| `AUTHENTICATED` | All authenticated users (including non-members of the Bitrix24 account) |
| `PUBLIC` | Everyone, without authentication |

## Examples

### curl — personal key

```bash
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-policy \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"accessPolicy": "PORTAL"}'
```

### curl — OAuth application

```bash
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-policy \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"accessPolicy": "NAMED_USERS"}'
```

### JavaScript — personal key

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access-policy`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ accessPolicy: 'NAMED_USERS' }),
  }
)
const { data } = await res.json()
console.log('New policy:', data.accessPolicy)
```

### JavaScript — OAuth application

```javascript
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/access-policy`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ accessPolicy: 'OWNER_ONLY' }),
  }
)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data.accessPolicy` | string | The new policy value (echo) |

## Response example

```json
{
  "success": true,
  "data": {
    "accessPolicy": "PORTAL"
  }
}
```

## Error response example

400 — the server is in OPEN mode:

```json
{
  "success": false,
  "error": {
    "code": "BLACKHOLE_ONLY",
    "message": "Access policy is a Black Hole feature. Server is in OPEN mode — switch to BLACKHOLE via PATCH /v1/infra/servers/:id/mode first."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | `accessPolicy` is not in the list of allowed values |
| 400 | `BLACKHOLE_ONLY` | The server is in OPEN mode — the policy is not applicable |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not provided |
| 401 | `INVALID_API_KEY` | The key is not recognized — no such key exists on the platform |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | The call was made with a Cowork key — such a key works with data only and cannot perform write operations. To issue a key that can, see [Project key for deploy](/docs/cowork/deploy-key) |
| 403 | `SERVER_ROLE_FORBIDDEN` | You are on this server's development team with the Developer role, and this operation is open to the Administrator role. `error.hint` carries your role, the required threshold and the list of calls that are open to you. Role breakdown — [List servers](/docs/infra/servers/list) |
| 403 | `SERVER_MANAGING_KEY_REQUIRED` | This key is bound to the application and server but does not manage the server. Use the server's managing API key or change the policy in your Vibecode account |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key cannot change Bitrix24 data, but the request widens the set of employees who open the app of a server with its own handler. Everyone who opens it passes their tokens to that handler |
| 404 | `NOT_FOUND` | The server does not exist, was deleted, or belongs to another API key while you are not on its development team |
| 409 | `AUDIENCE_APPROVAL_REQUIRED` | Wider access requires human approval. Access remains unchanged. Open `error.details.approvalUrl`, then retry the exact request with the original key and `approvalId` equal to `error.details.proposalId` |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

The full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **An approved request still needs to be applied.** On protected Bitrix24 accounts, widening access can require human approval. The response provides `proposalId`, `approvalUrl`, `expiresAt` and `retryOperation` in `error.details`. Send `approvalUrl` to a person authorized to approve access. [Check the request](./audience-proposals-get.md), then repeat the original PATCH after `APPROVED`, adding `approvalId`. Keep the same key and `accessPolicy`. The `retryOperation` object describes the approved operation and is not the HTTP request body.

- **`PUBLIC` is especially dangerous.** It makes the application accessible without any authentication — to any visitor from the internet. Policy changes are recorded in the Bitrix24 account's audit log.
- **`NAMED_USERS` and `DEPARTMENT` require non-empty access lists.** The policy change itself does not add users — the list is maintained separately via [`POST /access`](./access-add.md). If the list is empty under `NAMED_USERS`/`DEPARTMENT`, the application will be inaccessible to everyone except the owner (there is no automatic fallback to `OWNER_ONLY`).
- **The new policy also applies to sessions that are already open.** If it no longer admits a user, the application becomes unavailable to them within a minute. The exception is a switch to `OWNER_ONLY`: some open sessions keep working until they expire, up to 40 minutes, but can no longer be renewed. If you switch a server to `OWNER_ONLY` to close access immediately, allow for this delay.
- **A policy change does not close access through `share-url` links.** They are revoked separately — [Revoke a token](/docs/infra/access-tokens/delete).
- **When you switch back to `OWNER_ONLY`, the entries in `/access` stay in the database.** They are not applied unless the policy is `NAMED_USERS`/`DEPARTMENT`. To clear the history, delete the entries via [`DELETE /access/:accessId`](./access-delete.md).
- **When you switch the mode to OPEN, `accessPolicy` does not change**, but it is not applied either: in OPEN mode, protection is handled by SSH keys and iptables. On returning to BLACKHOLE, the policy becomes effective again.
- **`AUTHENTICATED` includes non-members of the Bitrix24 account.** Unlike `PORTAL`, `AUTHENTICATED` allows any authenticated Bitrix24 user (including those who are not members of your Bitrix24 account). It suits guest-form applications, but access is no longer limited to members of your own Bitrix24 account.
- **The API key owner always has access** — they are not removed from the list on a policy change. To revoke your own access, you need a request from a different key.
- **When the app is opened from the Bitrix24 catalog, the Bitrix24 account itself confirms membership.** The employee needs no Vibecode account: an app with the `PORTAL` policy (as well as `AUTHENTICATED` and `PUBLIC`) opens for every employee, exactly as promised. The platform additionally checks with Bitrix24 that this is an active employee, not a former one and not an external guest. Identity-based policies (`OWNER_ONLY`, `NAMED_USERS`, `DEPARTMENT`) do not open through this path — they resolve access per individual, so the employee has to sign in to Vibecode once.

## See also

- [Approving wider access](/docs/infra/access#approving-wider-access)
- [Access list](./access-list.md)
- [Add user/department](./access-add.md)
- [Delete access entry](./access-delete.md)
- [Search Bitrix24 users](./b24-users.md)
- [Switch mode](./mode.md)
