diff --git a/developer/terraform-best-practices.mdx b/developer/terraform-best-practices.mdx index 9ae468d8..d4d9ccb9 100644 --- a/developer/terraform-best-practices.mdx +++ b/developer/terraform-best-practices.mdx @@ -217,6 +217,7 @@ resource "conductorone_app_entitlement" "test_entitlement_update_multistep" { - **Terraform import is not required.** Reference the entitlement by ID using a data source lookup. - **JSON encoding is required** for `multi_step` provisioning and `account_provision` config blocks. - **Entitlement owners** are managed with a separate resource, [conductorone_app_entitlement_owner](https://registry.terraform.io/providers/ConductorOne/conductorone/latest/docs/resources/app_entitlement_owner). Owners are always a list of C1 users — the resource accepts `user_ids` only, and setting the list replaces any existing owners for that entitlement. See the example below. +- **App-level owners** are managed with [conductorone_app_owner](https://registry.terraform.io/providers/ConductorOne/conductorone/latest/docs/resources/app_owner), which takes an `app_id` and a `user_ids` list. Setting `user_ids` replaces any existing owners for the app, and changing either field forces the resource to be replaced. ### Example: manage entitlement owners @@ -233,6 +234,23 @@ resource "conductorone_app_entitlement_owner" "role_owners" { } ``` +### Example: manage app owners + +Use the same pattern with `conductorone_app_owner` to set the owners of an app, replacing any owners currently set. + +```hcl +resource "conductorone_app_owner" "aws_owners" { + app_id = data.conductorone_app.aws.id + user_ids = [ + data.conductorone_user.alice.id, + ] +} +``` + + +When looking up users, the [conductorone_user](https://registry.terraform.io/providers/ConductorOne/conductorone/latest/docs/data-sources/user) data source returns a single user matching your search criteria, while [conductorone_users](https://registry.terraform.io/providers/ConductorOne/conductorone/latest/docs/data-sources/users) returns a paginated `list` of matching users. Use `conductorone_user` when you need one user's ID (as in the examples above) and `conductorone_users` when you need to iterate over multiple users. + + `duration_grant` and `duration_unset` are mutually exclusive. Set `duration_grant` to a duration string in seconds (for example, `"3600s"` for one hour) to cap how long a grant lasts. Set `duration_unset = {}` for no maximum duration. Never set both. diff --git a/product/admin/groups.mdx b/product/admin/groups.mdx index a54a6212..28048237 100644 --- a/product/admin/groups.mdx +++ b/product/admin/groups.mdx @@ -124,6 +124,17 @@ Yes. Add the group's entitlement to an app's [requestable entitlements](/product Members added through a request aren't removed by the group's membership automation rule — the same protection that already applies to users you add manually. + + + +There is no dedicated groups endpoint in the C1 API. C1 groups are resources of the group resource type in the C1 app, so you fetch them with the app resource endpoints: + +1. Find the group resource type for the C1 app: `GET /api/v1/apps/{app_id}/resource_types` +2. List the group resources of that type: `GET /api/v1/apps/{app_id}/resource_types/{app_resource_type_id}/resources` +3. To get a group's entitlements (such as its member entitlement), list the entitlements associated with that resource: `GET /api/v1/apps/{app_id}/entitlements/resource_types/{app_resource_type_id}/resources/{app_resource_id}` + +In each request, `app_id` is the ID of the built-in C1 app. +