# Security Groups

Source: https://docs.quake.ai/docs/network/concepts/security-groups
Markdown: https://docs.quake.ai/docs/network/concepts/security-groups.md

---

# Security groups

The Network service ([OpenStack Neutron](https://docs.openstack.org/neutron/latest/)) implements security groups as **stateful** packet filters attached to instance **ports**. Each rule describes allowed traffic by direction (ingress or egress), IP protocol, optional port range, and remote address range in CIDR form (or by reference to another security group). They are the first place you express "who may SSH here" or "this tier may talk to the database on 5432."

Security groups attach rules to each **port**, so they track the network boundary closest to the workload without requiring a separate hardware firewall per VM.

## What security groups do

They combine into a virtual firewall around NICs. **Ingress** rules gate inbound connections; **egress** rules gate outbound. **Stateful** behavior means that when you allow a flow in one direction, return packets for established connections match the state table and are permitted without mirror micro-rules for ephemeral client ports.

ICMP "echo" for ping, traceroute-related types, and application protocols all use the same rule machinery; if you need ping for debugging, expose it explicitly instead of assuming defaults include it.

New instances typically land in a **default** security group whose baseline allows inbound from other members of that same group and outbound toward broad destinations. That default supports bootstrapping and traffic between instances in the same group; production systems add explicit ingress from reverse proxies or bastions only, and sometimes constrain egress to required endpoints for compliance.

You can attach **multiple** groups to one instance so web, admin, and compliance rules compose. One group can also span many instances when you treat a tier as a role.

## How rules are evaluated

<Figure caption="Security group packet evaluation: ingress and egress rules are checked against incoming and outgoing traffic on each port">

```mermaid
flowchart LR
    accTitle: Security group packet evaluation
    accDescr: Flowchart showing how ingress and egress traffic is evaluated against security group rules on a port, with matching packets allowed and non-matching packets dropped

    Inbound["Inbound<br/>packet"] --> IngressCheck{"Match<br/>ingress rule?"}
    IngressCheck -->|"Yes"| Allow1["Allow →<br/>instance"]
    IngressCheck -->|"No"| Drop1["Drop"]

    Instance["Instance<br/>response"] --> StateCheck{"Existing<br/>session?"}
    StateCheck -->|"Yes (stateful)"| Allow2["Allow →<br/>client"]
    StateCheck -->|"No"| EgressCheck{"Match<br/>egress rule?"}
    EgressCheck -->|"Yes"| Allow3["Allow →<br/>network"]
    EgressCheck -->|"No"| Drop2["Drop"]
```

</Figure>

Rules are allow lists: traffic must match an explicit permit. OpenStack evaluates security group rules as a set of permits (there is no separate "deny rule" row in the classic model; absence of allow means drop). Direction, protocol, ports, and remote prefixes must align for a packet to pass.

Because evaluation is stateful, short-lived responses to permitted client sessions return even if egress rules are narrower than you might expect for arbitrary UDP or TCP; still validate your egress policy against compliance needs.

## Changing policy safely

Updates apply immediately to every port using that security group, so a broad change can open or close many instances at once. Immediate propagation helps incident response and amplifies mistakes; prefer narrow ranges, change windows, and infrastructure-as-code review for shared groups.

## Interaction with ports and floating IPs

Security groups bind to **ports** on each NIC. If an instance has multiple NICs, each port can carry a different combination of groups; your database NIC might be far more restricted than a management NIC. Floating IP NAT resolves to the private address first; security groups then evaluate the permitted flows on that instance port.

## Practices that keep environments defensible

Apply **least privilege**: allow only the protocols and sources you need; default-deny is implicit where no rule matches. **Segment** by role (web, application, data) so a compromise in one group does not imply carte blanche elsewhere. **Audit** rules periodically as applications evolve. Pair filters with **logging and monitoring** (where the platform exposes them) to spot unexpected connection attempts.

Prefer referencing another security group as a source when tiers scale: "application servers may reach the database security group on 5432" stays correct when you add instances without editing CIDRs.

## Further reading

**On this platform:**

- [Create a security group](/docs/network/how-to/create-security-group): step-by-step setup via Console, CLI, and API
- [Create security group rules](/docs/network/how-to/create-security-group-rules): add ingress and egress rules
- [Security groups console](/reference/network/console/security-groups): console reference for security group management
- [Security groups CLI reference](/reference/network/security-groups-cli): all `openstack security group` commands

**External resources:**

- [OpenStack Neutron security group documentation](https://docs.openstack.org/neutron/latest/admin/intro-os-networking.html): upstream implementation details and admin configuration
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks): industry-standard hardening baselines for Linux instances
- [NIST SP 800-123: Guide to General Server Security](https://csrc.nist.gov/publications/detail/sp/800-123/final): vendor-neutral firewall and access control principles
