Terraform
Project Team Access API
The team access APIs are used to associate a team to permissions on a project. A single team-project
resource contains the relationship between the Team and Project, including the privileges the team has on the project.
Note: A team-project
resource represents a team's local permissions on a specific project. Teams can also have organization-level permissions that grant access to projects, and HCP Terraform uses whichever access level is higher. (For example: a team with the "manage projects" permission has admin access on all projects, even if their team-project
on a particular project only grants read access.) For more information, see Managing Project Access.
Any member of an organization can view team access relative to their own team memberships, including secret teams of which they are a member. Organization owners and project admins can modify team access or view the full set of secret team accesses. The organization token and the owners team token can act as an owner on these endpoints. (More about permissions.)
Project Team Access Levels
Access Level | Description |
---|---|
read | Read project and Read workspace access role on project workspaces |
write | Read project and Write workspace access role on project workspaces |
maintain | Read project and Admin workspace access role on project workspaces |
admin | Admin project, Admin workspace access role on project workspaces, create workspaces within project, move workspaces between projects, manage project team access |
custom | Custom access permissions on project and project's workspaces |
List Team Access to a Project
GET /team-projects
Status | Response | Reason |
---|---|---|
200 | JSON API document (type: "team-projects" ) | The request was successful |
404 | JSON API error object | Project not found or user unauthorized to perform action |
Query Parameters
These are standard URL query parameters; remember to percent-encode [
as %5B
and ]
as %5D
if your tooling doesn't automatically encode URLs.
This endpoint supports pagination with standard URL query parameters.
Parameter | Description |
---|---|
filter[project][id] | Required. The project ID to list team access for. |
page[number] | Optional. |
page[size] | Optional. |
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request GET \
"https://app.terraform.io/api/v2/team-projects?filter%5Bproject%5D%5Bid%5D=prj-ckZoJwdERaWcFHwi"
Sample Response
{
"data": [
{
"id": "tprj-TLznAnYdcsD2Dcmm",
"type": "team-projects",
"attributes": {
"access": "read",
"project-access": {
"settings": "read",
"teams": "none"
},
"workspace-access": {
"create": false,
"move": false,
"locking": false,
"delete": false,
"runs": "read",
"variables": "read",
"state-versions": "read",
"sentinel-mocks": "none",
"run-tasks": false
}
},
"relationships": {
"team": {
"data": {
"id": "team-KpibQGL5GqRAWBwT",
"type": "teams"
},
"links": {
"related": "/api/v2/teams/team-KpibQGL5GqRAWBwT"
}
},
"project": {
"data": {
"id": "prj-ckZoJwdERaWcFHwi",
"type": "projects"
},
"links": {
"related": "/api/v2/projects/prj-ckZoJwdERaWcFHwi"
}
}
},
"links": {
"self": "/api/v2/team-projects/tprj-TLznAnYdcsD2Dcmm"
}
}
],
"links": {
"self": "https://app.terraform.io/api/v2/team-projects?filter%5Bproject%5D%5Bid%5D=prj-ckZoJwdERaWcFHwi&page%5Bnumber%5D=1&page%5Bsize%5D=20",
"first": "https://app.terraform.io/api/v2/team-projects?filter%5Bproject%5D%5Bid%5D=prj-ckZoJwdERaWcFHwi&page%5Bnumber%5D=1&page%5Bsize%5D=20",
"prev": null,
"next": null,
"last": "https://app.terraform.io/api/v2/team-projects?filter%5Bproject%5D%5Bid%5D=prj-ckZoJwdERaWcFHwi&page%5Bnumber%5D=1&page%5Bsize%5D=20"
},
"meta": {
"pagination": {
"current-page": 1,
"page-size": 20,
"prev-page": null,
"next-page": null,
"total-pages": 1,
"total-count": 1
}
}
}
Show a Team Access relationship
GET /team-projects/:id
Status | Response | Reason |
---|---|---|
200 | JSON API document (type: "team-projects" ) | The request was successful |
404 | JSON API error object | Team access not found or user unauthorized to perform action |
Parameter | Description |
---|---|
:id | The ID of the team/project relationship. Obtain this from the list team access action described above. |
As mentioned in Add Team Access to a Project and Update to a Project, several permission attributes are not editable unless you set access
to custom
. If you set access
to read
, plan
, write
, or admin
, certain attributes are read-only and reflect the implicit permissions granted to the current access level.
For example, if you set access
to read
, the implicit permission level for project settings and workspace run is "read". Conversely, if you set the access level to admin
, the implicit permission level for the project settings is "delete", while the workspace runs permission is "apply".
Several permission attributes are not editable unless access
is set to custom
. When access is read
, plan
, write
, or admin
, these attributes are read-only and reflect the implicit permissions granted to the current access level.
For example, when access is read
, the implicit level for the project settings and workspace runs permissions are "read". Conversely, when the access level is admin
, the implicit level for the project settings is "delete" and the workspace runs permission is "apply". To see all of the implied permissions at different access levels, see Implied Custom Permission Levels.
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request GET \
https://app.terraform.io/api/v2/team-projects/tprj-s68jV4FWCDwWvQq8
Sample Response
{
"data": {
"id": "tprj-TLznAnYdcsD2Dcmm",
"type": "team-projects",
"attributes": {
"access": "read",
"project-access": {
"settings": "read",
"teams": "none"
},
"workspace-access": {
"create": false,
"move": false,
"locking": false,
"delete": false,
"runs": "read",
"variables": "read",
"state-versions": "read",
"sentinel-mocks": "none",
"run-tasks": false
}
},
"relationships": {
"team": {
"data": {
"id": "team-KpibQGL5GqRAWBwT",
"type": "teams"
},
"links": {
"related": "/api/v2/teams/team-KpibQGL5GqRAWBwT"
}
},
"project": {
"data": {
"id": "prj-ckZoJwdERaWcFHwi",
"type": "projects"
},
"links": {
"related": "/api/v2/projects/prj-ckZoJwdERaWcFHwi"
}
}
},
"links": {
"self": "/api/v2/team-projects/tprj-TLznAnYdcsD2Dcmm"
}
}
}
Add Team Access to a Project
POST /team-projects
Status | Response | Reason |
---|---|---|
200 | JSON API document (type: "team-projects" ) | The request was successful |
404 | JSON API error object | Project or Team not found or user unauthorized to perform action |
422 | JSON API error object | Malformed request body (missing attributes, wrong types, etc.) |
Request Body
This POST endpoint requires a JSON object with the following properties as a request payload.
Properties without a default value are required.
Key path | Type | Default | Description |
---|---|---|---|
data.type | string | Must be "team-projects" . | |
data.attributes.access | string | The type of access to grant. Valid values are read , write , maintain , admin , or custom . | |
data.relationships.project.data.type | string | Must be projects . | |
data.relationships.project.data.id | string | The project ID to which the team is to be added. | |
data.relationships.team.data.type | string | Must be teams . | |
data.relationships.team.data.id | string | The ID of the team to add to the project. | |
data.attributes.project-access.settings | string | "read" | If access is custom , the permission to grant for the project's settings. Can only be used when access is custom . Valid values include read , update , or delete . |
data.attributes.project-access.teams | string | "none" | If access is custom , the permission to grant for the project's teams. Can only be used when access is custom . Valid values include none , read , or manage . |
data.attributes.workspace-access.runs | string | "read" | If access is custom , the permission to grant for the project's workspaces' runs. Can only be used when access is custom . Valid values include read , plan , or apply . |
data.attributes.workspace-access.sentinel-mocks | string | "none" | If access is custom , the permission to grant for the project's workspaces' Sentinel mocks. Can only be used when access is custom . Valid values include none , or read . |
data.attributes.workspace-access.state-versions | string | "none" | If access is custom , the permission to grant for the project's workspaces state versions. Can only be used when access is custom . Valid values include none , read-outputs , read , or write . |
data.attributes.workspace-access.variables | string | "none" | If access is custom , the permission to grant for the project's workspaces' variables. Can only be used when access is custom . Valid values include none , read , or write . |
data.attributes.workspace-access.create | boolean | false | If access is custom , this permission allows the team to create workspaces in the project. |
data.attributes.workspace-access.locking | boolean | false | If access is custom , the permission granting the ability to manually lock or unlock the project's workspaces. Can only be used when access is custom . |
data.attributes.workspace-access.delete | boolean | false | If access is custom , the permission granting the ability to delete the project's workspaces. Can only be used when access is custom . |
data.attributes.workspace-access.move | boolean | false | If access is move , this permission allows the team to move workspaces into and out of the project. The team must also have permissions to the project(s) receiving the the workspace(s). |
data.attributes.workspace-access.run-tasks | boolean | false | If access is custom , this permission allows the team to manage run tasks within the project's workspaces. |
Sample Payload
{
"data": {
"attributes": {
"access": "read"
},
"relationships": {
"project": {
"data": {
"type": "projects",
"id": "prj-ckZoJwdERaWcFHwi"
}
},
"team": {
"data": {
"type": "teams",
"id": "team-xMGyoUhKmTkTzmAy"
}
}
},
"type": "team-projects"
}
}
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
--data @payload.json \
https://app.terraform.io/api/v2/team-projects
Sample Response
{
"data": {
"id": "tprj-WbG7p5KnT7S7HZqw",
"type": "team-projects",
"attributes": {
"access": "read",
"project-access": {
"settings": "read",
"teams": "none"
},
"workspace-access": {
"create": false,
"move": false,
"locking": false,
"runs": "read",
"variables": "read",
"state-versions": "read",
"sentinel-mocks": "none",
"run-tasks": false
}
},
"relationships": {
"team": {
"data": {
"id": "team-xMGyoUhKmTkTzmAy",
"type": "teams"
},
"links": {
"related": "/api/v2/teams/team-xMGyoUhKmTkTzmAy"
}
},
"project": {
"data": {
"id": "prj-ckZoJwdERaWcFHwi",
"type": "projects"
},
"links": {
"related": "/api/v2/projects/prj-ckZoJwdERaWcFHwi"
}
}
},
"links": {
"self": "/api/v2/team-projects/tprj-WbG7p5KnT7S7HZqw"
}
}
}
Update Team Access to a Project
PATCH /team-projects/:id
Status | Response | Reason |
---|---|---|
200 | JSON API document (type: "team-projects" ) | The request was successful |
404 | JSON API error object | Team Access not found or user unauthorized to perform action |
422 | JSON API error object | Malformed request body (missing attributes, wrong types, etc.) |
Parameter | Description | ||
---|---|---|---|
:id | The ID of the team/project relationship. Obtain this from the list team access action described above. | ||
data.attributes.access | string | The type of access to grant. Valid values are read , write , maintain , admin , or custom . |
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request PATCH \
--data @payload.json \
https://app.terraform.io/api/v2/team-projects/tprj-WbG7p5KnT7S7HZqw
Sample Payload
{
"data": {
"id": "tprj-WbG7p5KnT7S7HZqw",
"attributes": {
"access": "custom",
"project-access": {
"settings": "delete"
"teams": "manage",
},
"workspace-access" : {
"runs": "apply",
"sentinel-mocks": "read",
"state-versions": "write",
"variables": "write",
"create": true,
"locking": true,
"delete": true,
"move": true,
"run-tasks": true
}
}
}
}
Sample Response
{
"data": {
"id": "tprj-WbG7p5KnT7S7HZqw",
"type": "team-projects",
"attributes": {
"access": "custom",
"project-access": {
"settings": "delete"
"teams": "manage",
},
"workspace-access" : {
"runs": "apply",
"sentinel-mocks": "read",
"state-versions": "write",
"variables": "write",
"create": true,
"locking": true,
"delete": true,
"move": true,
"run-tasks": true
}
},
"relationships": {
"team": {
"data": {
"id": "team-xMGyoUhKmTkTzmAy",
"type": "teams"
},
"links": {
"related": "/api/v2/teams/team-xMGyoUhKmTkTzmAy"
}
},
"project": {
"data": {
"id": "prj-ckZoJwdERaWcFHwi",
"type": "projects"
},
"links": {
"related": "/api/v2/projects/prj-ckZoJwdERaWcFHwi"
}
}
},
"links": {
"self": "/api/v2/team-projects/tprj-WbG7p5KnT7S7HZqw"
}
}
}
Remove Team Access from a Project
DELETE /team-projects/:id
Status | Response | Reason |
---|---|---|
204 | The Team Access was successfully destroyed | |
404 | JSON API error object | Team Access not found or user unauthorized to perform action |
Parameter | Description |
---|---|
:id | The ID of the team/project relationship. Obtain this from the list team access action described above. |
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request DELETE \
https://app.terraform.io/api/v2/team-projects/tprj-WbG7p5KnT7S7HZqw
Implied Custom Permission Levels
As mentioned above, when setting team access levels (read
, write
, maintain
, or admin
), you can individually set the following permissions if you use the custom
access level.
The below table lists each access level alongside its implicit custom permission level. If you use the custom
access level and do not specify a certain permission's level, that permission uses the default value listed below.
Permissions | read | write | maintain | admin | custom default |
---|---|---|---|---|---|
project-access.settings | "read" | "read" | "read" | "delete" | "read" |
project-access.teams | "none" | "none" | "none" | "manage" | "none" |
workspace-access.runs | "read" | "apply" | "apply" | "apply" | "read" |
workspace-access.sentinel-mocks | "none" | "read" | "read" | "read" | "none" |
workspace-access.state-versions | "read" | "write" | "write" | "write" | "none" |
workspace-access.variables | "read" | "write" | "write" | "write" | "none" |
workspace-access.create | false | false | true | true | false |
workspace-access.locking | false | true | true | true | false |
workspace-access.delete | false | false | true | true | false |
workspace-access.move | false | false | false | true | false |
workspace-access.run-tasks | false | false | true | true | false |