Skip to content

Commit a3229a8

Browse files
authored
Merge pull request #35 from PostHog/vdekrijger-create-role-resources
feat(rbac): Add resources to support RBAC
2 parents a4d196f + 40ff960 commit a3229a8

File tree

93 files changed

+8535
-15
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+8535
-15
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ Acceptance tests run against a real PostHog instance and create actual resources
7575
export POSTHOG_API_KEY="your-api-key"
7676
export POSTHOG_PROJECT_ID="12345"
7777
export POSTHOG_HOST="https://us.posthog.com"
78-
export POSTHOG_ORGANIZATION_ID="your-org-uuid" # Required for project resource tests
78+
export POSTHOG_ORGANIZATION_ID="your-org-uuid" # Default for organization-scoped resources
79+
export POSTHOG_TEST_USER_EMAIL="user@example.com" # Email of existing org member for membership tests (not the one who owns the token)
7980

8081
make testacc
8182
```

docs/data-sources/user.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "posthog_user Data Source - posthog"
4+
subcategory: ""
5+
description: |-
6+
Look up a user by email within an organization. The user must be a member of the organization.
7+
---
8+
9+
# posthog_user (Data Source)
10+
11+
Look up a user by email within an organization. The user must be a member of the organization.
12+
13+
## Example Usage
14+
15+
```terraform
16+
# Look up a user by their email address
17+
data "posthog_user" "alice" {
18+
organization_id = "your-organization-uuid"
19+
email = "alice@example.com"
20+
}
21+
22+
# Use the user's UUID in other resources
23+
output "alice_uuid" {
24+
value = data.posthog_user.alice.uuid
25+
}
26+
27+
output "alice_name" {
28+
value = "${data.posthog_user.alice.first_name} ${data.posthog_user.alice.last_name}"
29+
}
30+
```
31+
32+
<!-- schema generated by tfplugindocs -->
33+
## Schema
34+
35+
### Required
36+
37+
- `email` (String) The email address of the user to look up.
38+
39+
### Optional
40+
41+
- `organization_id` (String) The organization ID to search for the user in. Defaults to the provider-level organization_id.
42+
43+
### Read-Only
44+
45+
- `first_name` (String) The first name of the user.
46+
- `is_email_verified` (Boolean) Whether the user's email address has been verified.
47+
- `last_name` (String) The last name of the user.
48+
- `organization_member_id` (String) The organization membership ID. Use this for `organization_member` in access controls.
49+
- `uuid` (String) The UUID of the user.

docs/resources/access_control.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "posthog_access_control Resource - posthog"
4+
subcategory: ""
5+
description: |-
6+
Manages access control for resources within a PostHog project.
7+
This resource allows you to set access levels for resource types (like feature flags, dashboards, etc.).
8+
You can set permissions at three levels:
9+
Project default: Applies to everyone in the project for this resource type. Omit both role and organization_member.Role-specific: Applies to members of a specific role. Set role.Member-specific: Applies to a specific organization member. Set organization_member.
10+
Additionally, you can scope to:
11+
Resource-type level: Applies to all resources of a type (e.g., all dashboards). Omit resource_id.Resource-instance level: Applies to a specific resource (e.g., one dashboard). Set resource_id.
12+
You can combine these: set a project default for all dashboards, or set a project default for a specific dashboard.
13+
~> Note: role and organization_member are mutually exclusive - you cannot specify both. Omit both for project defaults.
14+
~> Enterprise Feature: Role-based access control (RBAC) requires a PostHog Enterprise plan. See Access Control documentation https://posthog.com/docs/settings/access-control for more details.
15+
---
16+
17+
# posthog_access_control (Resource)
18+
19+
Manages access control for resources within a PostHog project.
20+
21+
This resource allows you to set access levels for resource types (like feature flags, dashboards, etc.).
22+
23+
You can set permissions at three levels:
24+
- **Project default**: Applies to everyone in the project for this resource type. Omit both `role` and `organization_member`.
25+
- **Role-specific**: Applies to members of a specific role. Set `role`.
26+
- **Member-specific**: Applies to a specific organization member. Set `organization_member`.
27+
28+
Additionally, you can scope to:
29+
- **Resource-type level**: Applies to all resources of a type (e.g., all dashboards). Omit `resource_id`.
30+
- **Resource-instance level**: Applies to a specific resource (e.g., one dashboard). Set `resource_id`.
31+
32+
You can combine these: set a project default for all dashboards, or set a project default for a specific dashboard.
33+
34+
~> **Note:** `role` and `organization_member` are mutually exclusive - you cannot specify both. Omit both for project defaults.
35+
36+
~> **Enterprise Feature:** Role-based access control (RBAC) requires a PostHog Enterprise plan. See [Access Control documentation](https://posthog.com/docs/settings/access-control) for more details.
37+
38+
## Example Usage
39+
40+
```terraform
41+
# --- Project Defaults (no role or organization_member) ---
42+
43+
# Set project-wide default: everyone can view surveys
44+
resource "posthog_access_control" "surveys_project_default" {
45+
resource = "survey"
46+
access_level = "viewer"
47+
}
48+
49+
# Set default for a specific dashboard: everyone can view this dashboard
50+
resource "posthog_access_control" "analytics_dashboard_default" {
51+
resource = "dashboard"
52+
resource_id = posthog_dashboard.analytics.id
53+
access_level = "viewer"
54+
}
55+
56+
# --- Role-based Access ---
57+
58+
# Grant a role editor access to all feature flags in the project
59+
resource "posthog_access_control" "engineering_feature_flags" {
60+
resource = "feature_flag"
61+
access_level = "editor"
62+
role = posthog_role.engineering.id
63+
}
64+
65+
# Grant a role viewer access to all dashboards
66+
resource "posthog_access_control" "support_dashboards" {
67+
resource = "dashboard"
68+
access_level = "viewer"
69+
role = posthog_role.support.id
70+
}
71+
72+
# Grant a role viewer access to a specific dashboard
73+
resource "posthog_access_control" "support_analytics_dashboard" {
74+
resource = "dashboard"
75+
resource_id = posthog_dashboard.analytics.id
76+
access_level = "viewer"
77+
role = posthog_role.support.id
78+
}
79+
80+
# Explicitly deny a role access to experiments (access_level = "none")
81+
resource "posthog_access_control" "support_no_experiments" {
82+
resource = "experiment"
83+
access_level = "none"
84+
role = posthog_role.support.id
85+
}
86+
87+
# --- User-specific Access ---
88+
89+
# Grant a specific user editor access to a specific dashboard
90+
resource "posthog_access_control" "alice_analytics_dashboard" {
91+
resource = "dashboard"
92+
resource_id = posthog_dashboard.analytics.id
93+
access_level = "editor"
94+
organization_member = posthog_organization_member.alice.id
95+
}
96+
```
97+
98+
<!-- schema generated by tfplugindocs -->
99+
## Schema
100+
101+
### Required
102+
103+
- `access_level` (String) The access level to grant. Common values are `none`, `viewer`, `editor`.
104+
- `resource` (String) The resource type to control access for. Valid values include: `action`, `alert`, `annotation`, `cohort`, `dashboard`, `experiment`, `feature_flag`, `insight`, `notebook`, `session_recording`, `survey`, etc.
105+
106+
### Optional
107+
108+
- `organization_member` (String) The organization member ID to grant access to (either `organization_member_id` from `posthog_user` data source, or `posthog_organization_member.<name>.id`). Mutually exclusive with `role`. If neither `role` nor `organization_member` is set, this becomes the project default for the resource type.
109+
- `project_id` (String) Project ID (environment) for this resource. Overrides the provider-level project_id.
110+
- `resource_id` (String) The ID of a specific resource to control access for. If omitted, the access control applies to all resources of the specified type.
111+
- `role` (String) The UUID of the role to grant access to. Mutually exclusive with `organization_member`. If neither `role` nor `organization_member` is set, this becomes the project default for the resource type.
112+
113+
### Read-Only
114+
115+
- `created_at` (String) Timestamp when the access control was created.
116+
- `id` (String) Composite identifier for the access control.
117+
- `updated_at` (String) Timestamp when the access control was last updated.
118+
119+
## Import
120+
121+
Import is supported using the following syntax:
122+
123+
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
124+
125+
```shell
126+
# Import format for project default (all resources of a type):
127+
# project_id/resource_type/default
128+
terraform import posthog_access_control.surveys_project_default 12345/survey/default
129+
130+
# Import format for project default on a specific resource:
131+
# project_id/resource_type/resource_id/default
132+
terraform import posthog_access_control.analytics_dashboard_default 12345/dashboard/999/default
133+
134+
# Import format for role-based access control (resource type level):
135+
# project_id/resource_type/role/role_id
136+
terraform import posthog_access_control.engineering_feature_flags 12345/feature_flag/role/abc-123-def
137+
138+
# Import format for member-based access control (resource type level):
139+
# project_id/resource_type/member/member_id
140+
terraform import posthog_access_control.alice_dashboards 12345/dashboard/member/xyz-456-uvw
141+
142+
# Import format for role-based access control (specific resource):
143+
# project_id/resource_type/resource_id/role/role_id
144+
terraform import posthog_access_control.role_specific_dashboard 12345/dashboard/999/role/abc-123-def
145+
146+
# Import format for member-based access control (specific resource):
147+
# project_id/resource_type/resource_id/member/member_id
148+
terraform import posthog_access_control.alice_specific_dashboard 12345/dashboard/999/member/xyz-456-uvw
149+
```
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "posthog_organization_member Resource - posthog"
4+
subcategory: ""
5+
description: |-
6+
Manages a user's membership in a PostHog organization.
7+
~> Warning: By default, destroying this resource will remove the user from the organization entirely.
8+
Set retain_on_destroy = true to keep the user in the organization when the resource is destroyed.
9+
Users must already be members of the organization (e.g., via invite) before this resource can manage them.
10+
---
11+
12+
# posthog_organization_member (Resource)
13+
14+
Manages a user's membership in a PostHog organization.
15+
16+
~> **Warning:** By default, destroying this resource will **remove the user from the organization entirely**.
17+
Set `retain_on_destroy = true` to keep the user in the organization when the resource is destroyed.
18+
Users must already be members of the organization (e.g., via invite) before this resource can manage them.
19+
20+
## Example Usage
21+
22+
```terraform
23+
# Look up an existing user by email
24+
data "posthog_user" "alice" {
25+
organization_id = "your-organization-uuid"
26+
email = "alice@example.com"
27+
}
28+
29+
# Manage Alice's organization membership level
30+
# Note: The user must already be a member of the organization (e.g., via invite)
31+
resource "posthog_organization_member" "alice" {
32+
organization_id = "your-organization-uuid"
33+
user_uuid = data.posthog_user.alice.uuid
34+
level = "admin" # or "member" / "owner"
35+
36+
# Set to true to keep the user in the organization when this resource is destroyed.
37+
# By default, destroying this resource removes the user from the organization entirely.
38+
retain_on_destroy = true
39+
}
40+
```
41+
42+
<!-- schema generated by tfplugindocs -->
43+
## Schema
44+
45+
### Required
46+
47+
- `user_uuid` (String) The UUID of the user. Use the posthog_user data source to look up users by email.
48+
49+
### Optional
50+
51+
- `level` (String) The access level for the member. Valid values are 'member', 'admin', or 'owner'. Defaults to 'member'.
52+
- `organization_id` (String) Organization ID for this resource. Overrides the provider-level organization_id.
53+
- `retain_on_destroy` (Boolean) If true, the user will remain in the organization when this resource is destroyed. Defaults to false.
54+
55+
### Read-Only
56+
57+
- `email` (String) The email address of the user.
58+
- `first_name` (String) The first name of the user.
59+
- `id` (String) The member ID.
60+
- `is_2fa_enabled` (Boolean) Whether two-factor authentication is enabled for the user.
61+
- `joined_at` (String) Timestamp when the user joined the organization.
62+
- `last_name` (String) The last name of the user.
63+
64+
## Import
65+
66+
Import is supported using the following syntax:
67+
68+
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
69+
70+
```shell
71+
# Import an organization member using the format: organization_id/user_uuid
72+
terraform import posthog_organization_member.alice your-organization-uuid/user-uuid
73+
```
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "posthog_project_default_access Resource - posthog"
4+
subcategory: ""
5+
description: |-
6+
Sets the default access level for a PostHog project.
7+
This determines the baseline access level for all organization members who don't have explicit access granted via roles or direct membership.
8+
~> Note: There is only one default access level per project. This resource is a singleton - creating multiple instances for the same project will cause conflicts.
9+
~> Destroy Behavior: Destroying this resource resets the default access level to none (most restrictive). It does not restore the previous value.
10+
~> Enterprise Feature: Role-based access control (RBAC) requires a PostHog Enterprise plan. See Access Control documentation https://posthog.com/docs/settings/access-control for more details.
11+
---
12+
13+
# posthog_project_default_access (Resource)
14+
15+
Sets the default access level for a PostHog project.
16+
17+
This determines the baseline access level for all organization members who don't have explicit access granted via roles or direct membership.
18+
19+
~> **Note:** There is only one default access level per project. This resource is a singleton - creating multiple instances for the same project will cause conflicts.
20+
21+
~> **Destroy Behavior:** Destroying this resource resets the default access level to `none` (most restrictive). It does not restore the previous value.
22+
23+
~> **Enterprise Feature:** Role-based access control (RBAC) requires a PostHog Enterprise plan. See [Access Control documentation](https://posthog.com/docs/settings/access-control) for more details.
24+
25+
## Example Usage
26+
27+
```terraform
28+
# Set the default access level for a project
29+
# Everyone without explicit access will have this level
30+
resource "posthog_project_default_access" "restrictive" {
31+
project_id = "your-project-id"
32+
access_level = "none" # Options: none, member, admin
33+
}
34+
35+
# Use with provider-level project_id
36+
resource "posthog_project_default_access" "default" {
37+
access_level = "member"
38+
}
39+
```
40+
41+
<!-- schema generated by tfplugindocs -->
42+
## Schema
43+
44+
### Required
45+
46+
- `access_level` (String) The default access level for the project. Valid values are `none`, `member`, or `admin`.
47+
48+
### Optional
49+
50+
- `project_id` (String) Project ID (environment) for this resource. Overrides the provider-level project_id.
51+
52+
### Read-Only
53+
54+
- `id` (String) The project ID (used as the resource identifier).
55+
56+
## Import
57+
58+
Import is supported using the following syntax:
59+
60+
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
61+
62+
```shell
63+
# Import using the project_id
64+
terraform import posthog_project_default_access.example your-project-id
65+
```

0 commit comments

Comments
 (0)