1---
2title: Organization governance
3description: Manage existing Neon organization access, billing alerts, and private-network associations with explicit ownership and restoration.
4---
5
6These resources configure an **existing** Neon organization. They use management
7API credentials, separate from Postgres roles, application users, and branch
8service credentials. Include `Neon.providers()` in your stack as described in
9[Setup](/neon/setup).
10
11| Resource | Controls | On destroy |
12| --- | --- | --- |
13| [OrganizationApiKey](/providers/neon/organizationapikey) | An organization key, optionally project-restricted | Revoke the exact recorded key |
14| [OrganizationMemberRole](/providers/neon/organizationmemberrole) | An existing member's organization role | Restore their original role, never remove membership |
15| [ProjectMemberRole](/providers/neon/projectmemberrole) | An existing member's direct project grant | Restore the original direct grant, or remove the new grant |
16| [OrganizationSpendingLimit](/providers/neon/organizationspendinglimit) | Monthly spending-alert threshold | Restore the original threshold, or remove the new threshold |
17| [OrganizationVPCEndpoint](/providers/neon/organizationvpcendpoint) | Registration of an existing AWS PrivateLink endpoint | Restore an adopted label, or unregister a new registration |
18| [ProjectVPCEndpoint](/providers/neon/projectvpcendpoint) | A project's association with an organization endpoint | Restore an adopted label, or remove a new association |
19
20## Prepare the deployment identity
21
22Choose an existing organization and have an administrator approve the specific
23access, spending, or network controls this stack will manage. For key creation
24and role controls, use a personal management API key belonging to an organization
25admin: key creation requires a personal admin key, and Alchemy's role safety
26checks must identify the authenticated actor. Avoid making the deployment actor
27the member whose role is being changed.
28
29An organization-wide key has broad administrative authority but is not accepted
30by every operation. A project-restricted key has Editor access to that project;
31it cannot manage project access or delete the project. Check Neon's
32[operation/key matrix](https://neon.com/docs/manage/orgs-api#matrix-of-operations-and-key-types)
33and [permissions model](https://neon.com/docs/manage/user-permissions) rather than
34assuming any valid key can administer the organization. Configure the deployment
35key using [Setup](/neon/setup), never as a Function environment variable.
36
37Use a separate non-admin test member for access experiments, and obtain explicit
38approval before changing a real member's role or a shared billing threshold.
39Plan and account entitlements remain Neon's responsibility; Alchemy does not
40upgrade the organization.
41
42## Find the organization and project IDs
43
44In the Neon Console, open **Organization Settings → General information** and
45copy the organization ID. Select the intended project and copy its ID from
46project settings, or use the `projectId` output of its completed Alchemy
47deployment. Verify it belongs to that organization.
48
49Role and spending controls need resolved properties on their first deployment so
50the original configuration can be persisted before mutation. Deploy a project
51first and then pass its resolved ID for an initial `ProjectMemberRole` control;
52do not use an unresolved project output to skip that checkpoint.
53
54## Find an existing membership ID
55
56Have the user join the organization through Neon's normal invitation process
57first. Alchemy's role resources do not invite users. With `NEON_API_KEY` supplied
58securely to this terminal and `NEON_ORG_ID` set to the selected organization,
59make a read-only request:
60
61```sh
62curl --fail-with-body --get \
63 "https://console.neon.tech/api/v2/organizations/$NEON_ORG_ID/members" \
64 --header "Authorization: Bearer $NEON_API_KEY" \
65 --data-urlencode "limit=100" \
66 --data-urlencode "sort_by=email" \
67 --data-urlencode "sort_order=asc"
68```
69
70Match the intended person's `user.email`, verify the account is active, and copy
71`members[].member.id`. This is the membership ID, not `member.user_id`. If the
72response includes `pagination.next`, repeat the request with
73`--data-urlencode "cursor=<returned cursor>"`, keeping the sort settings, until
74you find the member or exhaust the pages. Do not infer absence from the first
75page. These results contain personal information; keep them out of public logs.
76
77## Issue a project-restricted management key
78
79```typescript
80import * as Neon from "alchemy/Neon";
81
82const project = yield* Neon.Project("Application", {
83 orgId: "org-example",
84});
85
86const automation = yield* Neon.OrganizationApiKey("Automation", {
87 orgId: "org-example",
88 projectId: project.projectId,
89});
90```
91
92The `automation.key` output is a `Redacted<string>`. Neon returns this secret only
93at creation: preserve and protect the Alchemy state store. A matching key name
94cannot recover a missing secret or prove ownership. The resource fails rather
95than silently adopting another key, rotating a revoked key, or substituting your
96deployment credential.
97
98:::caution
99Omitting `projectId` issues an organization-wide management key. Prefer a
100project-restricted key. For Function storage and backend bindings, use
101[`Neon.Credential`](/providers/neon/credential) and the runtime bindings instead;
102a management key is not a branch service token.
103:::
104
105## Manage an existing member's role
106
107```typescript
108import * as Alchemy from "alchemy";
109
110const membership = yield* Neon.OrganizationMemberRole("DeveloperRole", {
111 orgId: "org-example",
112 memberId: authorizedMemberId,
113 role: "editor",
114}).pipe(Alchemy.adopt(true));
115```
116
117Use the **membership ID**, not an email address or user ID. Resource-scoped
118adoption authorizes managing this existing role and saves its original value
119before mutation. Destroy restores that value; it never removes the person from
120the organization. The resource refuses changes to the authenticated actor's own
121role. Neon determines which roles your organization supports. Initial role-control
122properties must be resolved. To change the member or project being controlled,
123remove the old control first so its original role is restored, then declare the
124new control.
125
126## Manage a direct project grant
127
128```typescript
129const reviewer = yield* Neon.ProjectMemberRole("ReviewerAccess", {
130 orgId: "org-example",
131 memberId: authorizedMemberId,
132 project: { projectId: deployedProjectId },
133 role: "viewer",
134});
135```
136
137Deploy the project first and pass its resolved ID when initially creating this
138control. The provider must capture the original grant before writing. An existing
139direct grant requires resource-scoped adoption, as in the organization-role
140example. Organization-inherited access and administrator overrides are not
141owned by this resource. Removing a direct grant can leave inherited access in
142place; it is not equivalent to removing every permission.
143
144## Set a monthly spending alert
145
146```typescript
147const spending = yield* Neon.OrganizationSpendingLimit("SpendingAlert", {
148 orgId: "org-example",
149 spendingLimitCents: 10000,
150}).pipe(Alchemy.adopt(true));
151```
152
153This sets a $100 monthly alert threshold. Neon sends notifications at 80% and
154100%; it **does not suspend compute or enforce a hard spending cap**. Supply a
155positive integer number of cents. An existing threshold requires adoption and
156is restored on destroy; a newly created threshold is removed. Setting a
157threshold below current spending can trigger a notification. Plan and admin
158requirements are enforced by Neon. Initial properties must be resolved so Alchemy
159can persist the original threshold before writing. Remove the control and restore
160its original threshold before declaring a control for another organization.
161
162## Register an existing private endpoint
163
164```typescript
165const network = yield* Neon.OrganizationVPCEndpoint("PrivateNetwork", {
166 orgId: "org-example",
167 regionId: "aws-us-east-2",
168 vpcEndpointId: "vpce-0123456789abcdef0",
169 label: "Application network",
170});
171```
172
173Create the AWS endpoint separately. This resource registers it with Neon; it
174never provisions or deletes the AWS endpoint, configures DNS, or blocks public
175connections. Private networking requires an entitled organization and a
176supported AWS region. Follow [Private networking](/neon/guides/private-networking)
177for entitlement, AWS endpoint creation, registration order, private DNS, and
178inside/outside-network connection checks.
179
180## Associate a project with the endpoint
181
182```typescript
183const access = yield* Neon.ProjectVPCEndpoint("PrivateAccess", {
184 project,
185 endpoint: network,
186 label: "Application access",
187});
188```
189
190The project and organization registration must share an organization and AWS
191region. This manages only this endpoint association, leaving other associations
192and the project's public-connectivity setting unchanged. Removing the last
193association can broaden connectivity. Existing associations require scoped
194adoption and have their original label restored on destroy.
195
196:::caution
197Neon prevents re-registering an endpoint in the same organization after it is
198unregistered. Destroying a newly managed registration can therefore be
199irreversible for that endpoint ID. Remove dependent project associations first.
200An adopted organization registration is preserved and its original label
201restored.
202:::
203
204## Ownership and recovery
205
206Keep governance state backed up. The original role, alert threshold, or network
207configuration is part of the restoration record, not something that can safely
208be reconstructed from desired properties. Cleanup refuses conflicting external
209changes rather than overwriting another administrator's settings.
210
211Serialize changes to each member, spending threshold, and endpoint association.
212These APIs do not provide conditional writes, so observe-before-write checks
213cannot prevent every concurrent edit. An ambiguous interrupted role change
214fails closed and needs operator reconciliation of the retained state.
215
216Before deployment, record the intended member/grant, alert threshold, or network
217association with the responsible administrator. After deployment, independently
218check the selected organization/project in the Console. After destroy, confirm
219the original role, grant, threshold, or adopted label was restored; deletion of a
220resource declaration is not proof that the expected access policy is in effect.
221A spending threshold can send notifications immediately if current spending is
222already above it, so coordinate that test with the billing owner.
223
224For missing state, reveal-once secrets, or conflicting external edits, follow
225[State and recovery](/neon/guides/state-recovery) before another mutation.
226
227Organization creation, membership invitations, and organization deletion are
228outside these resources. Invitations are deliberately excluded because the
229public API does not expose a corresponding revoke lifecycle.