> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nekt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Assign Object Permissions

> Grant, change, and revoke access to secrets and live connections in a single call.

The same declarative bulk upsert as [Assign Permissions](/platform-api/permissions/catalog/assign), applied to the resources that live outside the Catalog: **secrets** and **live connections**. Each assignment is a cross product of recipients and resources, and `permission_level: null` revokes.

## Request body

| Parameter     | Type             | Required | Description                                       |
| ------------- | ---------------- | -------- | ------------------------------------------------- |
| `assignments` | array of objects | Yes      | One or more assignment blocks. Must not be empty. |

Each object in `assignments`:

| Parameter          | Type                                     | Required | Description                                                                                                           |
| ------------------ | ---------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `permission_level` | `viewer`, `editor`, `manager`, or `null` | Yes      | The level to apply. `null` revokes.                                                                                   |
| `users`            | array of UUIDs                           | No       | Recipient users.                                                                                                      |
| `groups`           | array of UUIDs                           | No       | Recipient permission groups.                                                                                          |
| `secrets`          | array of UUIDs                           | No       | Target secrets.                                                                                                       |
| `live_connections` | array of UUIDs                           | No       | Target live connections.                                                                                              |
| `tools`            | array of strings                         | No       | **Live connections only.** Restrict the grant to a subset of the connection's available tools. Omit for the full set. |

## What the levels mean here

Secrets and live connections do not use the Catalog meaning of the levels.

| Level     | Secret                                                              | Live connection                                                       |
| --------- | ------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `viewer`  | See the metadata and reference the secret in Queries and Notebooks. | Use the connection's tools.                                           |
| `editor`  | Also edit the description and rotate the value.                     | Also edit the description and tags. Nothing else.                     |
| `manager` | Also manage access and delete the secret.                           | Also change config, status, slug, tools, and setup links, and delete. |

<Warning>
  The value of a secret is never readable through the API at any level, including `manager`. Only pipeline runtimes resolve it.
</Warning>

## Share a secret with a group

```bash theme={null}
curl --request POST \
  --url https://api.nekt.ai/api/v1/organization/object-permissions/ \
  --header "x-api-key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "assignments": [
      {
        "permission_level": "viewer",
        "groups": ["b8c5e1e3-6d02-4f45-ad20-8f4b6e2d0e13"],
        "secrets": ["c9d0e1f2-a3b4-45c6-87d8-e9f0a1b2c3d4"]
      }
    ]
  }'
```

## Scope a live connection to specific tools

`tools` narrows what the recipient may call. It is validated against each connection's **current available set** — a name the connection does not expose is rejected with `Connection '<slug>' has no available tools named: …`.

```bash theme={null}
curl --request POST \
  --url https://api.nekt.ai/api/v1/organization/object-permissions/ \
  --header "x-api-key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "assignments": [
      {
        "permission_level": "viewer",
        "users": ["3f7c1e88-9a41-4b2d-8e5f-6c0a2d4b9e11"],
        "live_connections": ["d1e2f3a4-b5c6-47d8-99e0-f1a2b3c4d5e6"],
        "tools": ["search_contacts", "get_contact"]
      }
    ]
  }'
```

Three rules govern `tools`, and all three return `400` when broken:

* It applies to live connections only. Sending it alongside `secrets` is an error.
* It cannot be combined with `manager` — a manager always holds the full set.
* Every name must be currently available on **every** connection in the same assignment.

<Note>
  Omitting `tools` is not the same as listing every tool. Omitted means "whatever is available", and it keeps tracking the connection as tools are added or removed. An explicit list is a fixed subset.
</Note>

<Warning>
  Removing a tool from a live connection's available set strips it from every grant that named it. Adding the tool back later does **not** restore those grants — you have to reassign them.
</Warning>

## Errors

| Status | When                                                                                                                   |
| ------ | ---------------------------------------------------------------------------------------------------------------------- |
| `400`  | A `tools` rule was broken, a recipient's membership is deactivated, or a referenced id is not visible to your API key. |
| `403`  | The key's ceiling does not allow the grant. See [Permissions flow](/platform-api/permissions/overview).                |

## Related

* [Permissions flow](/platform-api/permissions/overview) — the end-to-end walkthrough and the ceiling rules.
* [List Object Permission Recipients](/platform-api/permissions/objects/recipients) — where recipient ids come from.
* [Secrets](/workspace/secrets) — what a secret is and how levels behave in the app.


## OpenAPI

````yaml POST /api/v1/organization/object-permissions/
openapi: 3.0.3
info:
  title: Nekt API
  version: v1
  description: Nekt API Documentation
  contact:
    email: support@nekt.ai
servers:
  - url: https://api.nekt.ai
security: []
paths:
  /api/v1/organization/object-permissions/:
    post:
      tags:
        - v1
      description: >-
        Grants CRUD for the "Others" axis (secrets), mirroring
        LakehousePermissionsViewSet.


        The recipients listing lives in object_permission_recipients.py,
        mirroring the

        lakehouse permission.py / permission_recipients.py split.
      operationId: v1_organization_object_permissions_create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssignObjectPermission'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AssignObjectPermission'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssignObjectPermission'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignObjectPermission'
          description: ''
      security:
        - ApiKeyAuth: []
components:
  schemas:
    AssignObjectPermission:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/ObjectPermissionAssignment'
          writeOnly: true
        notify_members:
          type: boolean
          writeOnly: true
          default: false
        message:
          type: string
          writeOnly: true
        created:
          type: array
          items:
            $ref: '#/components/schemas/ObjectPermission'
          readOnly: true
        updated:
          type: array
          items:
            $ref: '#/components/schemas/ObjectPermission'
          readOnly: true
        revoked:
          type: array
          items:
            $ref: '#/components/schemas/ObjectPermission'
          readOnly: true
      required:
        - assignments
        - created
        - revoked
        - updated
    ObjectPermissionAssignment:
      type: object
      properties:
        users:
          type: array
          items:
            type: integer
          default: []
        groups:
          type: array
          items:
            type: string
            format: uuid
          default: []
        permission_level:
          nullable: true
          oneOf:
            - $ref: '#/components/schemas/PermissionLevelEnum'
            - $ref: '#/components/schemas/NullEnum'
        secrets:
          type: array
          items:
            type: string
            format: uuid
          default: []
        live_connections:
          type: array
          items:
            type: string
            format: uuid
          default: []
        tools:
          type: array
          items:
            type: string
          nullable: true
          description: >-
            Live connections only: restrict this assignment's accesses to a
            subset of the available tools (omitted/null = the full available
            set).
      required:
        - permission_level
    ObjectPermission:
      type: object
      description: A grant of access to a secret or a live connection.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        permission_level:
          $ref: '#/components/schemas/PermissionLevelEnum'
        tool_scope:
          nullable: true
          description: >-
            Live connections only: subset of the connection's available tools
            this access may use (NULL = the full available set, tracking it as
            it changes; MANAGER grants are always NULL)
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        user:
          type: string
          readOnly: true
          description: User (Expandable)
        group:
          type: string
          readOnly: true
          description: Group (Expandable)
        secret:
          type: string
          readOnly: true
          description: Secret (Expandable)
        live_connection:
          type: string
          readOnly: true
          description: Live connection (Expandable)
        granted_by:
          type: string
          readOnly: true
          description: Granted by (Expandable)
      required:
        - created_at
        - granted_by
        - group
        - id
        - live_connection
        - permission_level
        - secret
        - updated_at
        - user
    PermissionLevelEnum:
      enum:
        - manager
        - editor
        - viewer
      type: string
      description: |-
        * `manager` - Manager
        * `editor` - Editor
        * `viewer` - Viewer
    NullEnum:
      enum:
        - null
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: 'API Key authentication. Format: ''x-api-key: api_key'''

````