Security Groups

Resource-level firewall, inbound/outbound rules, port-based access control, protocol rules, and common configurations.

Security groups act as a virtual firewall at the resource level. They control inbound and outbound traffic for buckets, agents, APIs, and databases. Rules are stateful: if you allow inbound traffic on a port, the response is automatically allowed outbound.

How Security Groups Work

  • Resource-level — Attached to individual resources (not subnets)
  • Stateful — Return traffic is automatically allowed
  • Allow-only — You specify what to allow; everything else is denied by default
  • Multiple groups — A resource can have multiple security groups; rules are evaluated together (OR logic)

Inbound vs Outbound Rules

Inbound Rules

Control traffic coming into the resource. Define:

  • Source — CIDR block, another security group, or 0.0.0.0/0 (anywhere)
  • Port range — Single port (e.g., 443) or range (e.g., 8000-9000)
  • Protocol — TCP, UDP, or ICMP

Outbound Rules

Control traffic leaving the resource. Define:

  • Destination — CIDR block or security group
  • Port range — Same as inbound
  • Protocol — TCP, UDP, or ICMP

By default, outbound traffic is often allowed to anywhere. Restrict it for compliance or to limit data exfiltration.

Port-Based Access Control

Common Ports

PortProtocolServiceUse Case
22TCPSSHBastion/admin access
80TCPHTTPWeb traffic
443TCPHTTPSSecure web/API traffic
5432TCPPostgreSQLDatabase connections
6379TCPRedisCache/session store
7007TCPS3 Storage ProxyNFYio object storage
7010TCPAgent ServiceRAG/LLM API
3000TCPGatewayNFYio API gateway

Example Inbound Rule

Allow HTTPS from anywhere:

{
  "direction": "inbound",
  "protocol": "tcp",
  "port_range": "443",
  "source": "0.0.0.0/0",
  "description": "HTTPS from internet"
}

Allow PostgreSQL only from app security group:

{
  "direction": "inbound",
  "protocol": "tcp",
  "port_range": "5432",
  "source": "sg_app_servers",
  "description": "DB access from app tier"
}

Protocol Rules

TCP

Most common. Use for HTTP, HTTPS, SSH, database connections, custom APIs.

UDP

Use for DNS, NTP, streaming, or custom UDP services.

ICMP

Use for ping and traceroute. Often restricted to internal networks for troubleshooting.

Common Configurations

Web/API Server

{
  "inbound": [
    { "protocol": "tcp", "port_range": "80", "source": "0.0.0.0/0" },
    { "protocol": "tcp", "port_range": "443", "source": "0.0.0.0/0" },
    { "protocol": "tcp", "port_range": "22", "source": "10.0.0.0/8" }
  ],
  "outbound": [
    { "protocol": "all", "destination": "0.0.0.0/0" }
  ]
}

Storage Proxy (S3)

{
  "inbound": [
    { "protocol": "tcp", "port_range": "7007", "source": "10.0.0.0/16" },
    { "protocol": "tcp", "port_range": "443", "source": "0.0.0.0/0" }
  ]
}

Agent Service (RAG)

{
  "inbound": [
    { "protocol": "tcp", "port_range": "7010", "source": "sg_api_gateway" },
    { "protocol": "tcp", "port_range": "443", "source": "0.0.0.0/0" }
  ]
}

Database (PostgreSQL)

{
  "inbound": [
    { "protocol": "tcp", "port_range": "5432", "source": "sg_app_servers" }
  ],
  "outbound": []
}

Creating a Security Group

Via API

curl -X POST https://api.yourdomain.com/v1/security-groups \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web-servers-sg",
    "description": "Security group for web and API servers",
    "vpc_id": "vpc_abc123",
    "inbound_rules": [
      {
        "protocol": "tcp",
        "port_range": "443",
        "source": "0.0.0.0/0"
      }
    ]
  }'

Response:

{
  "id": "sg_xyz789",
  "name": "web-servers-sg",
  "vpc_id": "vpc_abc123",
  "inbound_rules": [...],
  "outbound_rules": [...],
  "created_at": "2026-03-01T12:00:00Z"
}

Attaching to a Resource

curl -X PATCH https://api.yourdomain.com/v1/buckets/my-bucket \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"security_group_ids": ["sg_xyz789"]}'

Best Practices

  1. Least privilege — Only allow ports and sources that are strictly needed
  2. Reference security groups — Use sg_xxx as source/destination instead of CIDR when possible
  3. Document rules — Use the description field for each rule
  4. Separate tiers — Different security groups for web, app, and data tiers

Next Steps