curl --request POST \
--url https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor"
}
'import requests
url = "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings"
payload = {
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
principal_type: 'user',
principal_id: '5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24',
role_id: 'roles/project.editor'
})
};
fetch('https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'principal_type' => 'user',
'principal_id' => '5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24',
'role_id' => 'roles/project.editor'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings"
payload := strings.NewReader("{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}"
response = http.request(request)
puts response.read_body{
"id": "1a3c5e7f-9b2d-4f6a-8e0c-2d4f6a8b0c1e",
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor",
"scope_type": "project",
"scope_id": "9b1d6e2f-4a3c-4f8b-a7e5-0c9d2b4f6e81",
"principal_name": "Hanako Yamada",
"principal_email": "[email protected]",
"revoked_identity_tokens": 2
}{
"error": "organization_id is required"
}{
"error": "organization_id is required"
}{
"error": "organization_id is required"
}{
"error": "user is not a member of this organization: invite them instead"
}Grant a role on a project
Grants a user or identity a project role. You can grant only roles whose permissions you hold yourself; organization and platform roles cannot be granted on a project. Granting an identity a permission it did not hold revokes its existing tokens, and the response says how many.
A user must already hold a role in the project’s organization, at
organization level or on any of its projects. Anyone else joins by
accepting an invitation (POST /v1/invitations).
curl --request POST \
--url https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor"
}
'import requests
url = "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings"
payload = {
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
principal_type: 'user',
principal_id: '5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24',
role_id: 'roles/project.editor'
})
};
fetch('https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'principal_type' => 'user',
'principal_id' => '5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24',
'role_id' => 'roles/project.editor'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings"
payload := strings.NewReader("{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qumo-deploy.com/v1/projects/{id}/iam-bindings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"principal_type\": \"user\",\n \"principal_id\": \"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24\",\n \"role_id\": \"roles/project.editor\"\n}"
response = http.request(request)
puts response.read_body{
"id": "1a3c5e7f-9b2d-4f6a-8e0c-2d4f6a8b0c1e",
"principal_type": "user",
"principal_id": "5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24",
"role_id": "roles/project.editor",
"scope_type": "project",
"scope_id": "9b1d6e2f-4a3c-4f8b-a7e5-0c9d2b4f6e81",
"principal_name": "Hanako Yamada",
"principal_email": "[email protected]",
"revoked_identity_tokens": 2
}{
"error": "organization_id is required"
}{
"error": "organization_id is required"
}{
"error": "organization_id is required"
}{
"error": "user is not a member of this organization: invite them instead"
}Authorizations
A personal access token (POST /v1/auth/tokens) or a machine
identity token (POST /v1/projects/{project_id}/identities/{identity_id}/tokens),
both prefixed qumo_pat_. A token's scopes cap what it can do; see
Scopes and permissions. A personal
token names no organization: on a route whose path names no project or
organization, pass ?organization_id=.
Path Parameters
The project's id.
Body
user, identity "user"
The user's or identity's id.
"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24"
The role to grant. roles/platform.admin is never grantable, and
roles/organization.admin only on an organization.
roles/project.viewer, roles/project.editor, roles/project.admin, roles/organization.admin "roles/project.editor"
Response
The created binding.
The binding a grant created, and what the grant revoked.
"1a3c5e7f-9b2d-4f6a-8e0c-2d4f6a8b0c1e"
user, identity "user"
The user's or identity's id.
"5e7a9c3b-1d2f-4b6e-8a0c-7f3d9e1b5a24"
"roles/project.editor"
project, organization, platform "project"
The project's or organization's id; the nil UUID for platform scope.
"9b1d6e2f-4a3c-4f8b-a7e5-0c9d2b4f6e81"
The user's or identity's name, in lists. Absent when the principal no longer exists.
"Hanako Yamada"
The user's email, in lists. Absent for identities.
How many of the identity's tokens the grant revoked, because it gave the identity a permission it did not hold. Absent when none were. Mint a new token after such a grant.
x >= 12