curl --request PATCH \
--url https://workspace.basaltic.sh/v1/users/{user_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"linux_username": "deploy-bot"
}
'import requests
url = "https://workspace.basaltic.sh/v1/users/{user_id}"
payload = { "linux_username": "deploy-bot" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({linux_username: 'deploy-bot'})
};
fetch('https://workspace.basaltic.sh/v1/users/{user_id}', 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://workspace.basaltic.sh/v1/users/{user_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'linux_username' => 'deploy-bot'
]),
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://workspace.basaltic.sh/v1/users/{user_id}"
payload := strings.NewReader("{\n \"linux_username\": \"deploy-bot\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://workspace.basaltic.sh/v1/users/{user_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"linux_username\": \"deploy-bot\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://workspace.basaltic.sh/v1/users/{user_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"linux_username\": \"deploy-bot\"\n}"
response = http.request(request)
puts response.read_body{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"crn": "crn:workspace:::organization/550e8400-e29b-41d4-a716-446655440000/user/550e8400-e29b-41d4-a716-446655440001",
"email": "john.doe@acme.com",
"name": "John Doe",
"linux_identity": {
"home_directory": "/home/bsu_200001",
"username": "bsu_200001",
"uid": 1000100000,
"gid": 1000100000
},
"added_at": "2026-01-15T09:30:00Z",
"tags": {
"environment": "production",
"team": "backend"
}
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "CONFLICT",
"message": "Resource with this name already exists",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Update user Linux username
Change the organization-scoped Linux username without changing UID, GID or home directory.
curl --request PATCH \
--url https://workspace.basaltic.sh/v1/users/{user_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"linux_username": "deploy-bot"
}
'import requests
url = "https://workspace.basaltic.sh/v1/users/{user_id}"
payload = { "linux_username": "deploy-bot" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({linux_username: 'deploy-bot'})
};
fetch('https://workspace.basaltic.sh/v1/users/{user_id}', 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://workspace.basaltic.sh/v1/users/{user_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'linux_username' => 'deploy-bot'
]),
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://workspace.basaltic.sh/v1/users/{user_id}"
payload := strings.NewReader("{\n \"linux_username\": \"deploy-bot\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://workspace.basaltic.sh/v1/users/{user_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"linux_username\": \"deploy-bot\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://workspace.basaltic.sh/v1/users/{user_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"linux_username\": \"deploy-bot\"\n}"
response = http.request(request)
puts response.read_body{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"crn": "crn:workspace:::organization/550e8400-e29b-41d4-a716-446655440000/user/550e8400-e29b-41d4-a716-446655440001",
"email": "john.doe@acme.com",
"name": "John Doe",
"linux_identity": {
"home_directory": "/home/bsu_200001",
"username": "bsu_200001",
"uid": 1000100000,
"gid": 1000100000
},
"added_at": "2026-01-15T09:30:00Z",
"tags": {
"environment": "production",
"team": "backend"
}
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "CONFLICT",
"message": "Resource with this name already exists",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}workspace:UpdateUser. See WORKSPACE permissions for the full list, what each one covers, and an example policy.Authorizations
An OAuth 2.0 bearer token, sent as Authorization: Bearer <token>.
This is the recommended way to authenticate.
Get one by exchanging a service account's access key pair at
POST /v1/oauth/token with grant_type=client_credentials. It is the
standard client-credentials grant, so any OAuth-aware library will
obtain and refresh it for you.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Tokens last an hour by default. The same access key pair is separately your AWS SigV4 credential for the S3-compatible object endpoint, which speaks nothing else.
Path Parameters
User ID
Body
Optional custom Linux login name, unique across users, service accounts and pending invitations in the organization. Reserved system names and the bsu_/bsa_ prefixes cannot be chosen. Omit on creation to generate a name. Renaming preserves UID, GID and home directory; existing sessions are not disconnected.
1 - 32^[a-z_][a-z0-9_-]{0,31}$"deploy-bot"
Response
User details
A platform user linked to the organization.
Show child attributes
Show child attributes

