GCP: Node & Edge Schema
The GCP connection transforms Google Cloud IAM identities, resources, and permissions into a connected graph structure within the SlashID platform. It supports both principal identities (human or service accounts) and policy-based access definitions, including deny policies that can be inherited from organization and folder levels.
Node Types
| Node Type | Description |
|---|---|
GCPPrincipal | A GCP identity such as a user, group, or service account |
GCPRole | A GCP IAM role (predefined or custom) |
GCPServiceAccount | A specific type of principal used for automated services |
GCPBucket | A Google Cloud Storage bucket |
BigQueryDataset | A dataset resource in BigQuery |
BigQueryTable | A table within a BigQuery dataset |
GCPCloudRunService | A deployed service in Cloud Run |
GCPComputeInstance | A Compute Engine VM instance |
GCPPolicyBinding | A policy binding (role-principal pair) used in IAM |
GCPPolicyDenyRule | An explicit deny rule defined within a policy |
IAMPolicy | Aggregated IAM policy used across resources |
Edge Relationships
Membership & Role Edges
| Edge Type | From Node | To Node | Description |
|---|---|---|---|
HAS_PERMISSION | GCPPrincipal | GCPRole | Indicates which role a principal is granted |
IS_ASSIGNED | GCPRole | GCPPolicyBinding | Indicates that a role is assigned via a binding |
IS_CREDENTIAL_OF | GCPServiceAccount | GCPPrincipal | Maps credentials to their identity owner |
Containment Edges
| Edge Type | From Node | To Node | Description |
|---|---|---|---|
CONTAINS | BigQueryDataset | BigQueryTable | Dataset-to-table structural relationship |
IS_CONTAINED_BY | BigQueryTable | BigQueryDataset | Reverse of CONTAINS |
CONTAINS | IAMPolicy | GCPPolicyDenyRule | Policy includes one or more deny rules |
Effective Permission Edges
These edges represent the effective permissions after evaluating GCP IAM policies, including deny policies inherited from organization and folder levels.
| Edge Type | From Node | To Node | Description |
|---|---|---|---|
ALLOWS_ACCESS_TO | GCPPrincipal | GCPBucket, BigQueryDataset, GCPCloudRunService | Effective allowed access after policy evaluation |
IS_ALLOWED_ACCESS_BY | Resource | GCPPrincipal | Reverse of ALLOWS_ACCESS_TO |
DENIES_ACCESS_TO | GCPPrincipal | Resource | Explicit deny from deny policies |
IS_DENIED_ACCESS_BY | Resource | GCPPrincipal | Reverse of DENIES_ACCESS_TO |
CAN_ACCESS | GCPPrincipal | GCPBucket, BigQueryDataset, GCPCloudRunService | Direct access relationship (legacy) |
Deny Policy Inheritance
GCP supports IAM Deny Policies that can block access even when allow policies would otherwise grant it. SlashID evaluates deny policies across the full resource hierarchy:
Organization
└── Deny Policies (inherited by all folders and projects)
└── Folder
└── Deny Policies (inherited by child folders and projects)
└── Project
└── Deny Policies (project-specific)
└── Resources
- Explicit deny takes precedence: If a deny policy matches, access is blocked regardless of allow policies
- Inheritance: Deny policies at organization level apply to all folders and projects
- CEL Conditions: Deny rules can include conditions (e.g.,
resource.name.startsWith("projects/prod-")) - Graph representation: Deny rules create
DENIES_ACCESS_TOedges in the identity graph
This is similar to AWS Service Control Policies (SCPs) - a deny at the organization level blocks access even if the project's IAM policy would allow it.
Examples
// Role assignments
(GCPPrincipal)-[:HAS_PERMISSION]->(GCPRole)
(GCPRole)-[:IS_ASSIGNED]->(GCPPolicyBinding)
// Effective permissions (recommended for access analysis)
(GCPPrincipal)-[:ALLOWS_ACCESS_TO]->(GCPBucket)
(GCPServiceAccount)-[:ALLOWS_ACCESS_TO]->(BigQueryDataset)
(GCPPrincipal)-[:DENIES_ACCESS_TO]->(GCPComputeInstance)
// Resource hierarchy
(BigQueryDataset)-[:CONTAINS]->(BigQueryTable)
(IAMPolicy)-[:CONTAINS]->(GCPPolicyDenyRule)
Query Examples
Find all identities with access to BigQuery datasets
MATCH (i:Identity)-[:ALLOWS_ACCESS_TO]->(d:Resource)
WHERE d.resource_type = "gcp_bigquery_dataset"
RETURN i.name, d.name;
Find identities blocked by deny policies
MATCH (i:Identity)-[:DENIES_ACCESS_TO]->(r:Resource)
RETURN i.name AS identity, r.name AS resource, r.resource_type;
Analyze deny rules inherited from organization level
MATCH (p:GCPPolicyDenyRule)
WHERE p.inherited_from_org = true
RETURN p.name, p.denied_permissions, p.denial_condition;
Find service accounts with both allowed and denied access to same resource
MATCH (sa:Identity)-[:ALLOWS_ACCESS_TO]->(r:Resource)
WHERE sa.entity_type = "GCPServiceAccount"
AND EXISTS {
MATCH (sa)-[:DENIES_ACCESS_TO]->(r)
}
RETURN sa.name, r.name AS resource;