Skip to content

Role Abstractions

cloudspells.core.abstractions.roles

Cloud-neutral role-based security posture descriptors.

A Role captures the ambient network behaviour of a class of resources — which subnet tier it belongs to, what outbound access it needs, and whether it accepts SSH management connections from upstream resources. It is the cloud-neutral counterpart of per-provider NSG/security-group rule sets.

The four-tier topology (public / private / secure / management) is universal across cloud providers; the predefined roles below encode the most common reference-architecture assignments.

Predefined roles:

  • INTERNET_EDGE — public-facing load balancers or bastion hosts.
  • APP_SERVER — private-tier application servers; NAT + service egress.
  • DATABASE — secure-tier databases; service egress only.
  • CACHE — private-tier caches and message brokers; same posture as APP_SERVER.
  • MANAGEMENT — management-tier monitoring agents and tooling; service egress only.
Exports

Role: Security posture dataclass. INTERNET_EDGE: Predefined role for internet-facing resources. APP_SERVER: Predefined role for private-tier application servers. DATABASE: Predefined role for secure-tier databases. CACHE: Predefined role for private-tier caches and message brokers. MANAGEMENT: Predefined role for management-tier tooling.

INTERNET_EDGE: Role = Role(subnet_tier=SUBNET_PUBLIC, egress_internet=False, egress_services=False, accept_management_ssh=False) module-attribute

Role for internet-facing load balancers and bastion hosts.

Resources carrying this role are placed in the public subnet (internet gateway route). Inbound ports are declared via the provider NSG ports= parameter.

accept_management_ssh=False because this role is the management entry point — it acts as the SSH source toward private-tier resources, not as an SSH target from another resource.

Example
from cloudspells.core.abstractions import INTERNET_EDGE
from cloudspells.providers.oci import Nsg

lb_nsg = Nsg("load-balancer", role=INTERNET_EDGE, ports=[HTTP, HTTPS], vcn=vcn,
             compartment_id=compartment_id)

APP_SERVER: Role = Role(subnet_tier=SUBNET_PRIVATE, egress_internet=True, egress_services=True, accept_management_ssh=True) module-attribute

Role for private-tier application servers.

Resources carrying this role are placed in the private subnet (NAT gateway + service gateway routes). Ambient rules include outbound access to the internet and to provider-managed services.

Example
from cloudspells.core.abstractions import APP_SERVER
from cloudspells.providers.oci import Nsg

web_nsg = Nsg("web-backend", role=APP_SERVER, vcn=vcn, compartment_id=compartment_id)

DATABASE: Role = Role(subnet_tier=SUBNET_SECURE, egress_internet=False, egress_services=True, accept_management_ssh=True) module-attribute

Role for secure-tier databases.

Resources carrying this role are placed in the secure subnet (service gateway only — no NAT, no internet path).

Example
from cloudspells.core.abstractions import DATABASE
from cloudspells.providers.oci import Nsg

db_nsg = Nsg("database", role=DATABASE, vcn=vcn, compartment_id=compartment_id)

CACHE: Role = Role(subnet_tier=SUBNET_PRIVATE, egress_internet=True, egress_services=True, accept_management_ssh=True) module-attribute

Role for private-tier caches and message brokers (Redis, Memcached, Kafka).

Identical security posture to APP_SERVER — private subnet, internet egress, service egress. Provided as a semantic alias so that the intent of each resource is clear from its role name.

Example
from cloudspells.core.abstractions import CACHE
from cloudspells.providers.oci import Nsg

cache_nsg = Nsg("redis", role=CACHE, vcn=vcn, compartment_id=compartment_id)

MANAGEMENT: Role = Role(subnet_tier=SUBNET_MANAGEMENT, egress_internet=False, egress_services=True, accept_management_ssh=True) module-attribute

Role for management-tier monitoring agents, bastion service, and tooling.

Resources carrying this role are placed in the management subnet (service gateway only — same isolation as the secure tier, but logically separated for operational tooling).

Example
from cloudspells.core.abstractions import MANAGEMENT
from cloudspells.providers.oci import Nsg

mgmt_nsg = Nsg("monitoring", role=MANAGEMENT, vcn=vcn, compartment_id=compartment_id)

Role dataclass

Security posture descriptor for a class of networked resources.

A Role encodes the ambient network behaviour of a security group — the rules that every resource of this type needs regardless of which peers it communicates with. Directional traffic relationships are declared separately by the provider's NSG/security-group implementation.

Attributes:

Name Type Description
subnet_tier SubnetTier

Which network tier resources carrying this role belong to. Used by compute spells to infer subnet placement when a role is supplied instead of an explicit subnet.

egress_internet bool

True adds an all-protocol egress rule to 0.0.0.0/0 (outbound via NAT Gateway or equivalent). Suitable for private-tier app servers that call external APIs. Not set for DATABASE, MANAGEMENT, or INTERNET_EDGE.

egress_services bool

True adds an all-protocol egress rule to the cloud provider's managed-services endpoint (OCI Service Gateway, AWS VPC Gateway, GCP Private Google Access). Required for any instance that calls provider-managed endpoints (object storage, container registry, etc.).

accept_management_ssh bool

True causes the provider NSG implementation to automatically include an SSH (port 22) management channel from the upstream NSG in addition to the application port. Set False for roles where SSH access arrives through a separate channel (e.g. a bastion service session).

Example
from cloudspells.core.abstractions import Role
from cloudspells.core.abstractions import SUBNET_PRIVATE

# Custom role: private tier, internet + service egress, no SSH from upstream.
proxy = Role(
    subnet_tier=SUBNET_PRIVATE,
    egress_internet=True,
    egress_services=True,
    accept_management_ssh=False,
)
Source code in packages/cloudspells-core/src/cloudspells/core/abstractions/roles.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@dataclass
class Role:
    """Security posture descriptor for a class of networked resources.

    A `Role` encodes the ambient network behaviour of a security group — the
    rules that every resource of this type needs regardless of which peers it
    communicates with.  Directional traffic relationships are declared
    separately by the provider's NSG/security-group implementation.

    Attributes:
        subnet_tier: Which network tier resources carrying this role belong to.
            Used by compute spells to infer subnet placement when a role is
            supplied instead of an explicit subnet.
        egress_internet: `True` adds an all-protocol egress rule to
            `0.0.0.0/0` (outbound via NAT Gateway or equivalent).  Suitable
            for private-tier app servers that call external APIs.  Not set for
            `DATABASE`, `MANAGEMENT`, or `INTERNET_EDGE`.
        egress_services: `True` adds an all-protocol egress rule to the cloud
            provider's managed-services endpoint (OCI Service Gateway, AWS
            VPC Gateway, GCP Private Google Access).  Required for any
            instance that calls provider-managed endpoints (object storage,
            container registry, etc.).
        accept_management_ssh: `True` causes the provider NSG implementation
            to automatically include an SSH (port 22) management channel from
            the upstream NSG in addition to the application port.  Set `False`
            for roles where SSH access arrives through a separate channel (e.g.
            a bastion service session).

    Example:
        ```python
        from cloudspells.core.abstractions import Role
        from cloudspells.core.abstractions import SUBNET_PRIVATE

        # Custom role: private tier, internet + service egress, no SSH from upstream.
        proxy = Role(
            subnet_tier=SUBNET_PRIVATE,
            egress_internet=True,
            egress_services=True,
            accept_management_ssh=False,
        )
        ```
    """

    subnet_tier: SubnetTier
    egress_internet: bool = False
    egress_services: bool = False
    accept_management_ssh: bool = True