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

# Removing Collaborators from Resources — v0.172.0

> Collaborators are moving off resource manifests and permissions off virtual account manifests, so a resource is no longer coupled to its authorization.

## Who Is Affected

* **If you manage access from the TrueFoundry UI:** no action is required. Existing access is preserved and can be managed from **Access Control**.
* **If you manage resources through GitOps or keep resource YAML in Git:** update those manifests during the transition period.

<Warning>
  **Action is only required if you manage resources through GitOps, or keep resource YAML in Git.** See [GitOps and YAML](#gitops-and-yaml) for what to change and by when. The migration command requires TrueFoundry CLI **>= 0.17.4**.
</Warning>

## What Is Changing

We are in the process of **removing collaborators from each resource**. This is our effort to **decouple a resource from its authorization**.

Until now, access to a resource—for example, who can use a model provider account—was stored inside the resource itself. Similarly, what a virtual account could access was stored inside the virtual account. This coupled each resource configuration to its access list.

From **v0.172.0**, access is described separately from the resource. You grant a **role** on a **resource** to a **subject** — a user, team, virtual account, or agent — from the **Access Control** screen, or with a standalone `role-binding` manifest. A single grant is just the sentence *"this **subject** has this **role** on this **resource**"*.

<Check>
  **No access is lost.** Every existing grant is preserved. Removing these fields from a form or a YAML file does not, by itself, take anyone's access away.
</Check>

The change is visible on three surfaces: **resource forms**, **virtual accounts**, and **generated YAML**.

## Collaborators Move Off Resource Forms

The **Collaborators** section is removed from resources that supported it, including model provider accounts, clusters, ML repos, secret groups, MCP servers, agents, and workspaces. In its place, the form points to **Access Control**.

The examples below use provider accounts from environments running before and after this change.

<Columns cols={2}>
  <Frame caption="Before: access was managed from the provider account form">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-collaborators-before.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=4d92d3475c2a2cf4c36b664218365af4" alt="Model provider account form with a Collaborators section listing users, a team, and their roles" width="1550" height="740" data-path="images/docs/change-announcements/model-collaborators-before.png" />
  </Frame>

  <Frame caption="After: the form points to Access Control">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-collaborators-after.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=a921be595d1d3a5d5b3d325b21a0f6cc" alt="Model provider account form for nm-gemini2 showing that Collaborators has moved to Access Control" width="924" height="245" data-path="images/docs/change-announcements/model-collaborators-after.png" />
  </Frame>
</Columns>

### How to Reach Access Control

The access list now has its own screen. On the resource list, click the **three dots** at the end of the row and choose **Access Control**.

<Frame caption="Model provider account → three dots → Access Control">
  <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-access-control-menu.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=db9028d6a7f6afc3cd5d12cf1073aee1" alt="The nm-gemini2 model provider account with its three-dot menu open and Access Control highlighted" width="925" height="168" data-path="images/docs/change-announcements/model-access-control-menu.png" />
</Frame>

Access Control lists everyone who has access, grouped by role, with a **Grant Access** button for adding someone new.

<Frame caption="Access Control for nm-gemini2: existing grants are preserved and grouped by role">
  <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-access-control.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=4a6677adb0c6b9f216c6c47b76681416" alt="Access Control for the nm-gemini2 provider account showing Provider Account Manager and Provider Account Access grants" width="924" height="380" data-path="images/docs/change-announcements/model-access-control.png" />
</Frame>

When you save a provider account that still contains `collaborators`, TrueFoundry shows the removal in the confirmation diff first. The block leaves the configuration; the access it described is kept under Access Control.

<Frame caption="Saving nm-gemini2: collaborators leave the configuration, existing access is retained">
  <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-update-diff-collaborators-removed.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=5f196c937caa908601fab01a291482a4" alt="Update confirmation for the nm-gemini2 provider account showing the collaborators block removed from the updated configuration" width="952" height="520" data-path="images/docs/change-announcements/model-update-diff-collaborators-removed.png" />
</Frame>

This is also recorded in your activity log—see [what audit logs will show](#faq) so the entry does not look alarming.

## Permissions Move Off Virtual Accounts

The **Permissions** section is gone from the virtual account form. A virtual account is now treated like any other subject: you give it access the same way you would a user or a team.

<Columns cols={2}>
  <Frame caption="Before: the form carried role selection and per-resource-type permissions">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/virtual-account-permissions-before.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=1f6d1a3c183112a1a50922ce11f20788" alt="New Virtual Account form with a Permissions section containing role selection and per-resource-type toggles" width="694" height="545" data-path="images/docs/change-announcements/virtual-account-permissions-before.png" />
  </Frame>

  <Frame caption="After: the form points to Access Control instead">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/virtual-account-access-control-after.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=07a148ca1971e8e59870ea716d1087ff" alt="New Virtual Account form showing a notice that the Permissions section has moved to Access Control" width="694" height="545" data-path="images/docs/change-announcements/virtual-account-access-control-after.png" />
  </Frame>
</Columns>

### How to Reach Virtual Account Permissions

On the **Virtual Accounts** list, click the **three dots** at the end of the row and choose **Manage Permissions**. This is the same screen the form's notice links to.

<Frame caption="Virtual Accounts list → three dots at the end of the row → Manage Permissions">
  <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/virtual-account-manage-permissions-menu.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=421bbb76ee3c3e58594d30797231ad12" alt="Virtual Accounts list row with the three-dot menu open, highlighting the Manage Permissions option alongside Edit, Activity Logs and Delete" width="834" height="225" data-path="images/docs/change-announcements/virtual-account-manage-permissions-menu.png" />
</Frame>

From there you can assign **organisation roles** to the virtual account and add **resource-specific permissions** to it. As with resources, removing `permissions` from a virtual account is recorded in your activity log — see [what audit logs will show](#faq).

## Generated YAML No Longer Contains These Fields

YAML that TrueFoundry generates for you — including the **Apply using YAML** drawer — no longer includes `collaborators` or virtual account `permissions`. If you copy a manifest out of the dashboard and notice the access list missing, that is expected.

<Columns cols={2}>
  <Frame caption="Before: the generated manifest included collaborators">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-yaml-before.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=254ea26e6e487c8b065df94392d1e0f7" alt="Apply using YAML for an AWS Bedrock provider account with its collaborators block highlighted" width="1050" height="900" data-path="images/docs/change-announcements/model-yaml-before.png" />
  </Frame>

  <Frame caption="After: the manifest describes only the provider account">
    <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/model-yaml-after.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=08177a714549b7a476869404b4e24a4f" alt="Apply using YAML for the nm-gemini2 provider account without collaborators and with a notice directing users to Access Control" width="610" height="545" data-path="images/docs/change-announcements/model-yaml-after.png" />
  </Frame>
</Columns>

## What You Need to Do

If you manage access from the TrueFoundry UI, no action is required. Continue using **Access Control** for resources and **Manage Permissions** for virtual accounts.

### GitOps and YAML

This is the only part of the change that asks something of you, and it applies if you keep resource YAML in Git — through GitOps, `tfy apply`, Terraform, or your own API client.

#### Nothing You Have in Git Breaks

<Check>
  **Your existing manifests keep applying successfully.** A manifest that still sets `collaborators` is accepted for **two months** (collaborators will retire on **15th November 2026**). Nothing fails on release day, and no pipeline needs an emergency fix.
</Check>

You can also start submitting manifests **without** these fields right away — that will not change who already has access. Here is exactly how each field is treated while both models are accepted:

| If the field is… | What happens |
| - | - |
| Omitted entirely | Existing access is left untouched |
| A non-empty list | Those grants replace the previous legacy grants for that field |
| `collaborators: []` | Legacy collaborator grants on that resource are cleared |
| `permissions: []` on a virtual account | Rejected — delete the virtual account instead if it should have no access |

<Note>
  The safe way to adopt the new model is to **stop sending the field** rather than sending an empty list. An omitted field is a no-op; an empty `collaborators` list is a deliberate instruction to revoke.
</Note>

#### How to Migrate Your Repository

The CLI rewrites your manifests for you (**TrueFoundry CLI >= 0.17.4**). It converts `collaborators`, virtual-account `permissions`, and non-model `authorized_subjects` into `role-binding` documents placed next to the resource they belong to, in the same file.

<Steps>
  <Step title="Commit your current state">
    Make sure your working tree is clean, so the rewrite shows up as a reviewable diff.
  </Step>

  <Step title="Rewrite your manifests">
    ```bash theme={"dark"}
    tfy migrate-gitops -d truefoundry
    ```

    This prints the planned changes, then updates the files on disk: grant fields are removed and the generated `role-binding` documents are appended to the same file. There is no dry-run flag — generated binding names include a random suffix, so a preview would not match what a later write produces. If any manifest cannot be converted, nothing is written. Review the `git diff` before continuing.
  </Step>

  <Step title="Preview and apply against the platform">
    ```bash theme={"dark"}
    tfy apply -d truefoundry --dry-run --show-diff
    tfy apply -d truefoundry
    ```

    The dry run shows what the platform would change. Once it looks right, drop `--dry-run`.
  </Step>
</Steps>

#### What the Rewrite Looks Like

**A model provider account with collaborators.** Before—access is embedded in the provider account:

```yaml theme={"dark"}
type: provider-account/google-gemini
name: nm-gemini2
auth_data:
  type: api-key
  apiKey: tfy-secret://truefoundry:model-provider-secrets:gemini-api-key
collaborators:
  - subject: user:alice@example.com
    role_id: provider-account-manager
  - subject: team:data-science
    role_id: provider-account-access
integrations:
  - type: integration/model/gemini
    name: gemini-flash
    model_id: gemini-flash
    model_types:
      - chat
```

After—the provider account describes only the account and its models. Each role becomes a separate role binding:

```yaml theme={"dark"}
type: provider-account/google-gemini
name: nm-gemini2
auth_data:
  type: api-key
  apiKey: tfy-secret://truefoundry:model-provider-secrets:gemini-api-key
integrations:
  - type: integration/model/gemini
    name: gemini-flash
    model_id: gemini-flash
    model_types:
      - chat
---
type: role-binding
name: pa-nm-gemini2-manager
subjects:
  - type: user
    name: alice@example.com
permissions:
  - resourceType: provider-account
    resourceFqn: tfy-tenant:google-gemini:nm-gemini2
    role: provider-account-manager
---
type: role-binding
name: pa-nm-gemini2-access
subjects:
  - type: team
    name: data-science
permissions:
  - resourceType: provider-account
    resourceFqn: tfy-tenant:google-gemini:nm-gemini2
    role: provider-account-access
```

**A virtual account with permissions.** These work the other way round — the grants sit on the subject and name the resources — so they collapse into a single binding called `va-<account name>`. Before:

```yaml theme={"dark"}
type: virtual-account
name: ci-bot
permissions:
  - resource_type: workspace
    resource_fqn: tfy-usea1-devtest:tfy-gateway-mtls
    role_id: workspace-editor
  - resource_type: workspace
    resource_fqn: tfy-usea1-devtest:tfy-gateway-staging
    role_id: workspace-viewer
```

After — everything else about the account is untouched:

```yaml theme={"dark"}
type: virtual-account
name: ci-bot
---
type: role-binding
name: va-ci-bot
subjects:
  - type: virtualaccount
    name: ci-bot
permissions:
  - resourceType: workspace
    resourceFqn: tfy-usea1-devtest:tfy-gateway-mtls
    role: workspace-editor
  - resourceType: workspace
    resourceFqn: tfy-usea1-devtest:tfy-gateway-staging
    role: workspace-viewer
```

A few things worth knowing when you hand-write these:

* **`subjects[].type`** is one of `user`, `team`, `virtualaccount`, or `agent`. For `user`, `name` is the email address; for the rest it is the resource name.
* **`resourceFqn`** identifies the resource receiving the grant. The CLI generates it during migration. If you write a binding by hand, copy the exact FQN from the resource page. In the example above, replace `tfy-tenant` with your tenant FQN.
* Each binding must be either **one subject with many permissions** or **many subjects with one permission** — not both many at once. Splitting per role, as above, always satisfies this.
* **`name`** is your own identifier for the binding, 3–64 lowercase characters. The CLI generates names for you; if you write bindings by hand, pick something you will recognize in a diff.

## Timeline

| Milestone | When |
| - | - |
| Fields become optional; forms and generated YAML stop showing them | Control plane **v0.172.0** |
| `collaborators` and virtual account `permissions` no longer accepted | **After two months** (collaborators will retire on **15th November 2026**) |

<Warning>
  Migrate your GitOps and programmatic manifests well before the removal date. After it, an apply that still sends these fields will be rejected.
</Warning>

## FAQ

<AccordionGroup>
  <Accordion title="What will I see in audit logs when collaborators or permissions are removed?">
    Applying a resource is recorded with its usual action — **Apply Provider Account**, **Apply Workspace**, **Apply Mcp Server**, and so on — and the summary lists `Collaborators` among the updated fields.

    <Frame caption="Updating nm-gemini2: the summary reports Collaborators among the changed fields">
      <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/audit-log-apply-provider-account-entry.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=c6eaa2eb9f756fafc5a36ceecdd46186" alt="Audit log entry for Apply Provider Account on nm-gemini2 reporting Collaborators and Integrations changed" width="926" height="110" data-path="images/docs/change-announcements/audit-log-apply-provider-account-entry.png" />
    </Frame>

    Opening the entry shows the diff: the `collaborators` block leaves the document. This records **authorization being lifted out of the resource** — it does not mean anyone lost access. The grants themselves live on as role bindings.

    <Frame caption="The collaborators block leaves the provider account document; the grant it described lives on as a role binding">
      <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/audit-log-provider-account-collaborators-removed-diff.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=1359ce6e9b8d4e675d5878543c2cc562" alt="Audit log diff for nm-gemini2 showing the collaborators block present in the original version and absent from the updated version" width="990" height="500" data-path="images/docs/change-announcements/audit-log-provider-account-collaborators-removed-diff.png" />
    </Frame>

    The same applies to a virtual account: removing `permissions` is recorded against the virtual account, and the grants it described are preserved.
  </Accordion>

  <Accordion title="What do audit logs look like when access is granted or revoked from the dashboard?">
    Granting or removing access is recorded as **Create Access Grants** or **Revoke Grant**, naming the resource and the role involved.

    <Frame caption="Grants created and revoked, each naming the resource, its type, and the role">
      <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/audit-log-grant-created-revoked.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=d91d56e7b13db5ce30d1d4ddea7f8e5f" alt="Audit log list showing Create Access Grants and Revoke Grant entries with the resource name, resource type, role, and actor for each entry" width="931" height="569" data-path="images/docs/change-announcements/audit-log-grant-created-revoked.png" />
    </Frame>
  </Accordion>

  <Accordion title="What do audit logs look like when role bindings are applied from YAML?">
    Applying a `role-binding` manifest is recorded as **Apply Role Binding**, naming the binding and how many subjects it covers. This is what you will see after running the migration and applying.

    <Frame caption="Role bindings applied from YAML, each naming the binding and its subject count">
      <img src="https://mintcdn.com/truefoundry/Rs6o3yTGBtBc7VCQ/images/docs/change-announcements/audit-log-role-binding-applied.png?fit=max&auto=format&n=Rs6o3yTGBtBc7VCQ&q=85&s=67463995391bf07350bcac9fa04088b8" alt="Audit log list showing Apply Role Binding entries with role binding names and subject counts" width="931" height="443" data-path="images/docs/change-announcements/audit-log-role-binding-applied.png" />
    </Frame>

    See [Audit Logging](/docs/platform/audit-logging) for how to filter and search these entries.
  </Accordion>

  <Accordion title="Will anyone lose access when collaborators disappear from the form or YAML?">
    No. Every existing grant is preserved and is visible under **Access Control** on the resource.
  </Accordion>

  <Accordion title="I don't use GitOps. Do I need to do anything?">
    No. Grant and review access from **Access Control** exactly as you do today.
  </Accordion>

  <Accordion title="How do I give someone access to a resource now?">
    Open the resource list, click the **three dots** on the row, and choose **Access Control**. Click **Grant Access**, then pick the subject (user, team, virtual account, or agent) and the role to give them.
  </Accordion>

  <Accordion title="How do I give a virtual account access to resources?">
    Treat it like any other subject: grant it a role from the resource's **Access Control** screen, or add permissions to it from **Manage Permissions** on the virtual account. Do not add `permissions` to virtual account YAML going forward.
  </Accordion>

  <Accordion title="Can I keep using my old manifests until the removal date?">
    Yes. They continue to apply successfully during the transition window. We recommend migrating early so the change lands on your schedule rather than on the deadline.
  </Accordion>

  <Accordion title="Can I roll back if the migration output looks wrong?">
    Yes. `tfy migrate-gitops` only edits local files, so `git checkout` restores them. Nothing reaches the platform until you run `tfy apply`.
  </Accordion>
</AccordionGroup>

## References

* [Manage User Roles and Permissions](/docs/platform/manage-user-roles-and-permissions)
* [Virtual Account Management](/docs/platform/virtual-account-management)
* [Setup GitOps using TrueFoundry](/docs/setup-gitops-using-truefoundry)
* [Using `tfy apply`](/docs/using-tfy-apply)
* [Audit Logging](/docs/platform/audit-logging)

***

If you have questions about the migration or run into anything unexpected, reach out to [**support@truefoundry.com**](mailto:support@truefoundry.com) — we're happy to help.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.