# Policies API Reference

The Policies API lets you create, read, update, and delete RBAC policies and assign them to teams, users, and service accounts.
All endpoints are under the `/rbac/` base path and require a Service Account token with Admin role.

Replace `<your-instance>` with your Kloudfuse hostname and `<sa-token>` with a valid Service Account token.

For background on how policies control stream access, see [RBAC Policy Best Practices](https://docs.kloudfuse.com/platform/4.1.0/administration/authorization/policies/best-practices/).
For the Teams API, see [Teams API Reference](https://docs.kloudfuse.com/platform/4.1.0/reference/api/teams/).

## List Policies

Returns all policies defined in the system.

```bash
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/policies"
```

Response

```json
{
  "policies": [
    {
      "name": "All Access",
      "scope": {
        "type": "all",
        "filters": [
          { "key": "kf_stream", "op": "=~", "value": "logs|metrics|events|apm|rum" }
        ]
      }
    },
    {
      "name": "Production Logs",
      "scope": {
        "type": "custom",
        "filters": [
          { "key": "kf_stream", "op": "=~", "value": "logs" },
          { "key": "env",       "op": "=",  "value": "production" }
        ]
      }
    },
    {
      "name": "No Access",
      "scope": {
        "type": "none",
        "filters": [
          { "key": "kf_stream", "op": "=~", "value": "logs|metrics|events|apm|rum" }
        ]
      }
    }
  ]
}
```

## Get a Policy

Returns a single policy by name. URL-encode the policy name if it contains spaces or special characters.

```bash
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/policies/Production%20Logs"
```

Response

```json
{
  "name": "Production Logs",
  "scope": {
    "type": "custom",
    "filters": [
      { "key": "kf_stream", "op": "=~", "value": "logs" },
      { "key": "env",       "op": "=",  "value": "production" }
    ]
  }
}
```

## Create a Policy

Creates a new policy with the specified scope and filters.

```bash
curl -H "Authorization: Bearer <sa-token>" \
     -H "Content-Type: application/json" \
     -X POST "https://<your-instance>/rbac/policies" \
     -d '{
       "name": "Production Logs",
       "scope": {
         "type": "custom",
         "filters": [
           { "key": "kf_stream", "op": "=~", "value": "logs" },
           { "key": "env",       "op": "=",  "value": "production" }
         ]
       }
     }'
```

### Scope types

| `type` | Behaviour |
| --- | --- |
| `all` | Full access to all data in every stream. The `filters` field is ignored for access decisions. |
| `none` | No access to any stream. |
| `custom` | Access restricted to data matching the `filters` array. All filters apply to every query (AND logic within a policy; OR logic across policies on the same team). |

### Filter fields

| Field | Type | Description |
| --- | --- | --- |
| `key` | string | Label key to filter on. Use `kf_stream` to restrict by stream type, or any label key such as `env` or `kube_namespace`. |
| `op` | string | Operator: `=` (exact match), `!=` (exclude), `=~` (regex match), `!~` (regex exclude). |
| `value` | string | Value or regex pattern. Use `|` to OR multiple values in a regex: `logs|metrics`. |

Common `kf_stream` values: `logs`, `metrics`, `events`, `apm`, `rum`.

## Update a Policy

Replaces a policy’s scope and filters in full. The policy name in the URL and body must match. To rename a policy, delete and recreate it.

```bash
curl -H "Authorization: Bearer <sa-token>" \
     -H "Content-Type: application/json" \
     -X PUT "https://<your-instance>/rbac/policies/Production%20Logs" \
     -d '{
       "name": "Production Logs",
       "scope": {
         "type": "custom",
         "filters": [
           { "key": "kf_stream", "op": "=~", "value": "logs|metrics" },
           { "key": "env",       "op": "=",  "value": "production" }
         ]
       }
     }'
```

## Delete a Policy

Deletes a policy and removes all its team, user, and service account assignments.
Returns `204 No Content` with an empty response body.

```bash
curl -H "Authorization: Bearer <sa-token>" \
     -X DELETE "https://<your-instance>/rbac/policies/Production%20Logs"
```

## List Policy Assignments

Returns all teams, users, and service accounts assigned to a policy.

```bash
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/policies/Production%20Logs/mappings"
```

Response

```json
{
  "mappings": [
    {
      "policy_name": "Production Logs",
      "entity_type": "group",
      "entity_name": "ops-team",
      "created_at": "2026-04-21T19:27:41.829667Z"
    },
    {
      "policy_name": "Production Logs",
      "entity_type": "user",
      "entity_name": "alice@example.com",
      "created_at": "2026-04-20T10:00:00.000000Z"
    }
  ]
}
```

## Assign a Policy

Assigns a policy to a team (`group`), user, or service account.

```bash
# Assign to a team
curl -H "Authorization: Bearer <sa-token>" \
     -H "Content-Type: application/json" \
     -X POST "https://<your-instance>/rbac/policies/Production%20Logs/mappings" \
     -d '{
       "policy_name": "Production Logs",
       "entity_type": "group",
       "entity_name": "ops-team"
     }'

# Assign to a user
curl -H "Authorization: Bearer <sa-token>" \
     -H "Content-Type: application/json" \
     -X POST "https://<your-instance>/rbac/policies/Production%20Logs/mappings" \
     -d '{
       "policy_name": "Production Logs",
       "entity_type": "user",
       "entity_name": "alice@example.com"
     }'

# Assign to a service account
curl -H "Authorization: Bearer <sa-token>" \
     -H "Content-Type: application/json" \
     -X POST "https://<your-instance>/rbac/policies/Production%20Logs/mappings" \
     -d '{
       "policy_name": "Production Logs",
       "entity_type": "service_account",
       "entity_name": "my-pipeline-sa"
     }'
```

## Remove a Policy Assignment

Removes a policy assignment from a team, user, or service account.
Returns `204 No Content` on success.

```bash
# Remove from a team
curl -H "Authorization: Bearer <sa-token>" \
     -X DELETE "https://<your-instance>/rbac/policies/Production%20Logs/mappings/group/ops-team"

# Remove from a user
curl -H "Authorization: Bearer <sa-token>" \
     -X DELETE "https://<your-instance>/rbac/policies/Production%20Logs/mappings/user/alice%40example.com"

# Remove from a service account
curl -H "Authorization: Bearer <sa-token>" \
     -X DELETE "https://<your-instance>/rbac/policies/Production%20Logs/mappings/service_account/my-pipeline-sa"
```

## Get Effective Policies

Returns all policies assigned to an identity and the resolved per-stream access after combining all policies with OR logic.

```bash
# For a team
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/groups/ops-team/effective-policies"

# For a user
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/users/alice%40example.com/effective-policies"

# For a service account
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/service-accounts/my-pipeline-sa/effective-policies"
```

Response

```json
{
  "name": "ops-team",
  "entity_type": "group",
  "policies": [
    {
      "name": "Production Logs",
      "scope": {
        "type": "custom",
        "filters": [
          { "key": "kf_stream", "op": "=~", "value": "logs|metrics" },
          { "key": "env",       "op": "=",  "value": "production" }
        ]
      }
    }
  ],
  "scopes": {
    "logs":    [{ "type": "custom", "filters": [{ "key": "env", "op": "=", "value": "production" }], "policy_name": "Production Logs" }],
    "metrics": [{ "type": "custom", "filters": [{ "key": "env", "op": "=", "value": "production" }], "policy_name": "Production Logs" }],
    "events":  [{ "type": "none", "policy_name": "default-deny-policy" }],
    "apm":     [{ "type": "none", "policy_name": "default-deny-policy" }],
    "rum":     [{ "type": "none", "policy_name": "default-deny-policy" }]
  },
  "direct_policy_count": 1,
  "total_policy_count": 1
}
```

The `scopes` object shows the resolved access per stream.
A `default-deny-policy` entry means no assigned policy grants access to that stream — the `default_rbac_policy` cluster setting determines the fallback behavior.

## Get Allowed Filter Labels

Returns the label keys available for use in policy filters, grouped by stream type.

```bash
curl -H "Authorization: Bearer <sa-token>" \
  "https://<your-instance>/rbac/allowed-labels"
```

Response

```json
{
  "apm": [
    "kf_platform", "availability_zone", "cloud_account_id",
    "kube_cluster_name", "kube_namespace", "project", "region", "service_name"
  ],
  "rum": [
    "application.id", "service", "env", "geo.country_iso_code"
  ]
}
```

### Error Codes

| HTTP Status | Meaning |
| --- | --- |
| `200` | Success. |
| `201` | Policy or mapping created. |
| `204` | Delete succeeded (empty response body). |
| `400` | Bad request — invalid scope type, missing required field, or entity not found. |
| `401` | Missing or invalid `Authorization` header. |
| `403` | Insufficient permissions. |
| `404` | Policy or mapping not found. |
| `409` | Conflict — a policy with that name already exists.
