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

# Team member key permissions

> Why an invited team member cannot create a virtual key by default, how to grant it, and exactly what isolation holds between two members of the same team.

You create a workspace, create a team, invite an internal user, and they log in and try to make a virtual key. They get:

```
Team member does not have permission to generate key for this team.
Ask your proxy admin to configure the team member permission settings.
```

Nothing is broken. Team members start with almost no key permissions, and the grant has to be made deliberately

## Why it happens

A team carries a `team_member_permissions` list naming the key-management routes its members may call. Members always get a baseline of `/key/info` and `/key/health`, and nothing else unless you add it

A team created without that list ends up with `[]`, which means *explicitly nothing*, so members fall back to the baseline. `/key/generate` is not in it

<Note>
  The error message is accurate. It just does not say where to go, which is why people usually meet this problem twice before finding the setting
</Note>

## Granting it

<Tabs>
  <Tab title="Dashboard">
    Open the team, go to the **Member Permissions** tab, and tick the routes members should have. It sits on the team's own page, beside Members and Settings
  </Tab>

  <Tab title="API">
    Read the current setting and everything available:

    ```bash theme={null}
    curl -s "$FORCEAI_URL/team/permissions_list?team_id=$TEAM_ID" \
      -H "Authorization: Bearer $FORCEAI_KEY"
    ```

    Then set it. This grant lets a member create, list, delete and regenerate their own keys:

    ```bash theme={null}
    curl -s -X POST "$FORCEAI_URL/team/permissions_update" \
      -H "Authorization: Bearer $FORCEAI_KEY" -H 'Content-Type: application/json' -d '{
      "team_id": "'"$TEAM_ID"'",
      "team_member_permissions": [
        "/key/generate",
        "/key/list",
        "/key/delete",
        "/key/regenerate",
        "/key/{key_id}/regenerate",
        "/key/info"
      ]}'
    ```
  </Tab>
</Tabs>

<Tip>
  Grant `/key/list` alongside `/key/generate`. Without it a member creates a key and then cannot see it, which looks broken in a different way
</Tip>

## Choosing a grant

| Grant                    | Routes                                                                              | Fits                                                                                          |
| ------------------------ | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Create only              | `/key/generate`                                                                     | Members need a key and an admin curates the rest                                              |
| Own keys, full lifecycle | `+ /key/list`, `/key/delete`, `/key/regenerate`, `/key/{key_id}/regenerate`         | The usual choice. A member is self-sufficient for their own keys                              |
| Full key management      | `+ /key/block`, `/key/unblock`, `/key/bulk_update`, `/key/service-account/generate` | Convenient, and lets a member block another member's key and mint service-account credentials |

The full list of available routes comes back from `/team/permissions_list`, and includes spend and activity routes as well as key routes

## What isolation you get

The grant is per team, but ownership is enforced per user underneath it. With the "own keys, full lifecycle" grant above and two members in one team:

| Attempt                                       | Result                                              |
| --------------------------------------------- | --------------------------------------------------- |
| user1 lists keys                              | Sees only their own                                 |
| user1 asks for every key in the team          | Sees only their own                                 |
| user1 asks with `user_id=user2`               | Returns nothing                                     |
| user1 creates a key for themselves            | Allowed                                             |
| user1 creates a key **for user2**             | Refused, "User can only create keys for themselves" |
| user1 deletes user2's key                     | `403`, "You are not authorized to delete this key"  |
| An admin views or deletes any key in the team | Allowed                                             |

<Check>
  Granting the team does not let members reach each other's keys. Listing is scoped to the caller, and creation, deletion and modification all check ownership. Proxy admins bypass those checks, which is what lets an admin clean up after anyone
</Check>

### One caveat worth knowing

`/key/info` grants read access to any member of the key's team, so a member holding another member's **raw key string** can read that key's metadata

This is not a discovery path. The lookup is by the key value itself, and no listing call will surface another member's keys, as the table above shows. Anyone holding someone else's secret can already use it to make billed calls, which is worse than reading its budget and model list. Treat it as one more reason not to share key strings, rather than as a way for members to inspect each other

## Defaults for new teams

Granting one team changes only that team. A team created afterwards starts at the baseline again

<Warning>
  That is deliberate. Making key creation the default for every future team means each new team can mint keys unless somebody remembers to narrow it. Decide it per team, or set your own default consciously
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The member still gets the permission error after the grant">
    Confirm it saved by reading `/team/permissions_list` back. Check you granted the team they are actually creating the key under, and that they picked that team in the Key Ownership dialog
  </Accordion>

  <Accordion title="The member can create a key but the list is empty">
    `/key/list` was not granted. Add it
  </Accordion>

  <Accordion title="The member cannot see the team in the create-key dialog">
    That is team membership, not key permissions. Check they are listed under the team's Members tab
  </Accordion>

  <Accordion title="An admin needs to delete a member's key">
    Proxy admins bypass the ownership check and can delete any key, with no grant required
  </Accordion>
</AccordionGroup>
