Networking

Preview — pending review

This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.

Edit (replace) a security rule

PUT
/scopes/{scopeId}/network/security-groups/{securityGroupId}/security-rules/{securityRuleId}

Replaces rule securityRuleId of a security group with the rule in the body — the "Edit rule" action of the detail view's rule tables. Neutron security group rules are immutable, so the edit is performed server-side as one workflow. For a change of direction/protocol/ports/remote the edited rule is ADDED first and the old rule is then removed, so the traffic the old rule allowed has no window with neither rule in place; if that removal fails both rules stay (both are listed) and the operation ends FAILED. When the provider reports the add as the very rule being edited (Neutron's duplicate check ignores the description) that rule is never removed by the add step. A description-only change is applied by recreating the rule (remove, then add with the new description — a brief gap without the rule); if the recreate fails the old rule is restored and the operation ends FAILED. Validation: the same field rules as adding a rule (direction, etherType, protocol, port range and exactly one remote source) → 422 VALIDATION_FAILED; the parent security group must exist in the scope and be visible to the caller → 404 NOT_FOUND; securityRuleId must reference a rule of that group → 404 NOT_FOUND; contributor or higher → 403 FORBIDDEN. Async & state: Asynchronous — returns 202 with an Operation; the group's rule list carries the edited rule (at the old rule's position, keyed by the provider rule id) once the operation SUCCEEDS. resource.updated SSE frames are emitted for the parent security-group resource. Errors: 401 unauthenticated; 403 caller lacks write rights; 404 unknown group or rule; 412 when If-Match is supplied and stale; 422 invalid rule; 500 on workflow errors. Idempotency/Concurrency: Idempotency-Key is optional; replaying the same key returns the original 202 Operation. If-Match with the parent group's ETag guards against editing a rule of a group that changed since it was read.

Authorization

bearerToken
headerAuthorizationBearer <token>

An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.

Path Parameters

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

securityGroupId*string

Identifier of the parent security group.

securityRuleId*string

Identifier of the rule to edit.

Header Parameters

Idempotency-Key?string

Optional; recommended for safe retries. When sent, the same key+body within 24h replays the original result and the same key with a different body is 409 CONFLICT; keys are unique per tenant. When an API token or service-account (bearer) caller omits it, the request is applied once with no replay protection (a retry may apply it again). A console session gets one from the edge.

Formatuuid
If-Match?string

ETag for optimistic concurrency on mutations/deletes; mismatch results in 412.

Request Body

application/json
  1. body

Payload of the "Add security group rule" dialog. Exactly one of remoteCidr or remoteGroup must be set.

direction*string

Traffic direction (Inbound = ingress, Outbound = egress).

Value in"ingress""egress"
etherType*string

Address family the rule matches.

Value in"IPv4""IPv6"
protocol*string

L4 protocol; ports must be null for icmp/any.

Value in"tcp""udp""icmp""any"
portMin?|

"Port from" — start of the port range (1-65535); null for icmp/any, or null together with portMax for a tcp/udp all-ports rule.

portMax?|

"Port to" — end of the port range (1-65535, >= portMin); null for icmp/any, or null together with portMin for a tcp/udp all-ports rule.

remoteCidr?|

Source / dest CIDR the rule matches; null when remoteGroup is used.

remoteGroup?|

Peer security group reference matched instead of a CIDR; null when remoteCidr is used.

description?string

Optional human-readable purpose of the rule.

Lengthlength <= 255

Response Body

Rule edit accepted. Track via the returned operation.

application/json
  1. response

A long-running operation record. GET /operations/{operationId} returns its current state.

id*string

Operation identifier, unique platform-wide.

action*string

Canonical action id that started this operation, e.g. compute.instance.create.

state*OperationState

State machine for long-running operations. PENDING and RUNNING are transitional; the rest are terminal.

Value in"PENDING""RUNNING""SUCCEEDED""FAILED""CANCELLED"
resourceKind?|

Kind of the target resource (matches RealtimeEvent.kind), null for resource-less actions.

resourceId?|

Identifier of the target resource; null until the resource is allocated.

resourceName?|

Human-readable name of the target resource captured when the operation was opened; null when unknown or the resource has been deleted (clients fall back to resourceId).

principalId?|

Subject id (user id/email or service-account id) of the actor that initiated this operation, captured at the create chokepoint; null on internal/worker paths with no request-scoped principal or for historical rows. This is the real actor the Activity feed renders.

sourceIp?|

Source IP address of the request that initiated this operation; null when unavailable (internal/worker paths, historical rows).

progressPercent?|

Best-effort progress; null when the action does not report progress.

Range0 <= value <= 100
error?|null

Populated only when state is FAILED (or CANCELLED with partial rollback notes).

warning?|null

Non-fatal degradation recorded on an operation that still SUCCEEDED - the primary action completed but something explicitly requested could not be delivered (e.g. publicIp was requested at instance create but no floating IP could be assigned). On a CANCELLED create it reports that the provider resource had already been created and was kept (live and billed until deleted; details.disposition = left_in_place). Same code+message shape as error so clients render both uniformly; null when the operation ran without degradation.

startedAt?|

When the worker began executing; null while PENDING.

finishedAt?|

When a terminal state was reached; null while transitional.

createdAt*string
updatedAt*string
curl -X PUT "https://example.com/scopes/string/network/security-groups/string/security-rules/string" \  -H "Content-Type: application/json" \  -d '{    "direction": "ingress",    "etherType": "IPv4",    "protocol": "tcp"  }'
{  "id": "string",  "action": "string",  "state": "PENDING",  "resourceKind": "string",  "resourceId": "string",  "resourceName": "string",  "principalId": "string",  "sourceIp": "string",  "progressPercent": 0,  "error": {    "code": "string",    "message": "string",    "field": "string",    "details": {},    "retryable": false  },  "warning": {    "code": "string",    "message": "string",    "field": "string",    "details": {},    "retryable": false  },  "startedAt": "string",  "finishedAt": "string",  "createdAt": "string",  "updatedAt": "string"}