Update a security group
curl --request PUT \
--url https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "web-servers-sg-updated",
"description": "Updated security group for web servers",
"rules": [
{
"external_id": "sgr-existing123-v1",
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 8080,
"port_range_max": 8080,
"remote_ip_prefix": "0.0.0.0/0",
"description": "Updated: Allow traffic on port 8080"
},
{
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 3000,
"port_range_max": 3000,
"remote_ip_prefix": "10.0.0.0/8",
"description": "New rule: Allow internal API traffic"
}
]
}
'import requests
url = "https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}"
payload = {
"name": "web-servers-sg-updated",
"description": "Updated security group for web servers",
"rules": [
{
"external_id": "sgr-existing123-v1",
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 8080,
"port_range_max": 8080,
"remote_ip_prefix": "0.0.0.0/0",
"description": "Updated: Allow traffic on port 8080"
},
{
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 3000,
"port_range_max": 3000,
"remote_ip_prefix": "10.0.0.0/8",
"description": "New rule: Allow internal API traffic"
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'web-servers-sg-updated',
description: 'Updated security group for web servers',
rules: [
{
external_id: 'sgr-existing123-v1',
direction: 'ingress',
protocol: 'tcp',
port_range_min: 8080,
port_range_max: 8080,
remote_ip_prefix: '0.0.0.0/0',
description: 'Updated: Allow traffic on port 8080'
},
{
direction: 'ingress',
protocol: 'tcp',
port_range_min: 3000,
port_range_max: 3000,
remote_ip_prefix: '10.0.0.0/8',
description: 'New rule: Allow internal API traffic'
}
]
})
};
fetch('https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}', 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.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'web-servers-sg-updated',
'description' => 'Updated security group for web servers',
'rules' => [
[
'external_id' => 'sgr-existing123-v1',
'direction' => 'ingress',
'protocol' => 'tcp',
'port_range_min' => 8080,
'port_range_max' => 8080,
'remote_ip_prefix' => '0.0.0.0/0',
'description' => 'Updated: Allow traffic on port 8080'
],
[
'direction' => 'ingress',
'protocol' => 'tcp',
'port_range_min' => 3000,
'port_range_max' => 3000,
'remote_ip_prefix' => '10.0.0.0/8',
'description' => 'New rule: Allow internal API traffic'
]
]
]),
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.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}"
payload := strings.NewReader("{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"security_group": {
"id": "sg-abc123xyz-v1",
"account_id": "<string>",
"project_id": "<string>",
"name": "<string>",
"description": "<string>",
"metadata": {},
"rules": [
{
"id": "sgr-abc123xyz-v1",
"security_group_id": "<string>",
"protocol": "<string>",
"port_range_min": 123,
"port_range_max": 123,
"remote_ip_prefix": "<string>",
"remote_security_group_id": "<string>",
"icmp_type": 123,
"icmp_code": 123,
"priority": 123,
"description": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"is_deleted": true
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"is_deleted": true
},
"message": "Security group updated successfully"
}{
"error": "Validation failed: name is required",
"code": "BAD_REQUEST"
}{
"error": "account_id mismatch between header and path",
"code": "UNAUTHORIZED"
}{
"error": "Security group not found",
"code": "NOT_FOUND"
}{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}Firewall
Update a Security Groups
Updates a security group’s name, description, metadata, and/or rules.
When updating rules:
- Rules with
external_idwill be updated - Rules without
external_idwill be created as new rules - Existing rules not included in the request will remain unchanged
PUT
/
api
/
v1
/
accounts
/
{accountId}
/
projects
/
{projectId}
/
security-groups
/
{securityGroupId}
Update a security group
curl --request PUT \
--url https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "web-servers-sg-updated",
"description": "Updated security group for web servers",
"rules": [
{
"external_id": "sgr-existing123-v1",
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 8080,
"port_range_max": 8080,
"remote_ip_prefix": "0.0.0.0/0",
"description": "Updated: Allow traffic on port 8080"
},
{
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 3000,
"port_range_max": 3000,
"remote_ip_prefix": "10.0.0.0/8",
"description": "New rule: Allow internal API traffic"
}
]
}
'import requests
url = "https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}"
payload = {
"name": "web-servers-sg-updated",
"description": "Updated security group for web servers",
"rules": [
{
"external_id": "sgr-existing123-v1",
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 8080,
"port_range_max": 8080,
"remote_ip_prefix": "0.0.0.0/0",
"description": "Updated: Allow traffic on port 8080"
},
{
"direction": "ingress",
"protocol": "tcp",
"port_range_min": 3000,
"port_range_max": 3000,
"remote_ip_prefix": "10.0.0.0/8",
"description": "New rule: Allow internal API traffic"
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'web-servers-sg-updated',
description: 'Updated security group for web servers',
rules: [
{
external_id: 'sgr-existing123-v1',
direction: 'ingress',
protocol: 'tcp',
port_range_min: 8080,
port_range_max: 8080,
remote_ip_prefix: '0.0.0.0/0',
description: 'Updated: Allow traffic on port 8080'
},
{
direction: 'ingress',
protocol: 'tcp',
port_range_min: 3000,
port_range_max: 3000,
remote_ip_prefix: '10.0.0.0/8',
description: 'New rule: Allow internal API traffic'
}
]
})
};
fetch('https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}', 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.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'web-servers-sg-updated',
'description' => 'Updated security group for web servers',
'rules' => [
[
'external_id' => 'sgr-existing123-v1',
'direction' => 'ingress',
'protocol' => 'tcp',
'port_range_min' => 8080,
'port_range_max' => 8080,
'remote_ip_prefix' => '0.0.0.0/0',
'description' => 'Updated: Allow traffic on port 8080'
],
[
'direction' => 'ingress',
'protocol' => 'tcp',
'port_range_min' => 3000,
'port_range_max' => 3000,
'remote_ip_prefix' => '10.0.0.0/8',
'description' => 'New rule: Allow internal API traffic'
]
]
]),
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.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}"
payload := strings.NewReader("{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aion.xyz/api/v1/accounts/{accountId}/projects/{projectId}/security-groups/{securityGroupId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"web-servers-sg-updated\",\n \"description\": \"Updated security group for web servers\",\n \"rules\": [\n {\n \"external_id\": \"sgr-existing123-v1\",\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 8080,\n \"port_range_max\": 8080,\n \"remote_ip_prefix\": \"0.0.0.0/0\",\n \"description\": \"Updated: Allow traffic on port 8080\"\n },\n {\n \"direction\": \"ingress\",\n \"protocol\": \"tcp\",\n \"port_range_min\": 3000,\n \"port_range_max\": 3000,\n \"remote_ip_prefix\": \"10.0.0.0/8\",\n \"description\": \"New rule: Allow internal API traffic\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"security_group": {
"id": "sg-abc123xyz-v1",
"account_id": "<string>",
"project_id": "<string>",
"name": "<string>",
"description": "<string>",
"metadata": {},
"rules": [
{
"id": "sgr-abc123xyz-v1",
"security_group_id": "<string>",
"protocol": "<string>",
"port_range_min": 123,
"port_range_max": 123,
"remote_ip_prefix": "<string>",
"remote_security_group_id": "<string>",
"icmp_type": 123,
"icmp_code": 123,
"priority": 123,
"description": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"is_deleted": true
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"is_deleted": true
},
"message": "Security group updated successfully"
}{
"error": "Validation failed: name is required",
"code": "BAD_REQUEST"
}{
"error": "account_id mismatch between header and path",
"code": "UNAUTHORIZED"
}{
"error": "Security group not found",
"code": "NOT_FOUND"
}{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}Authorizations
JWT token from authentication service
Headers
Account ID from authentication (must match path accountId)
User ID performing the action
Unique request ID for tracing
Path Parameters
Account external ID
Pattern:
^acct-[a-zA-Z0-9]+-v1$Project external ID
Pattern:
^proj-[a-zA-Z0-9]+-v1$Security group external ID
Pattern:
^sg-[a-zA-Z0-9]+-v1$Body
application/json
⌘I
