Skip to content

Instantly share code, notes, and snippets.

@Wintus
Last active June 6, 2023 15:12
Show Gist options
  • Save Wintus/c09dbeaaf6e661127f23ede1e4dde05d to your computer and use it in GitHub Desktop.
Save Wintus/c09dbeaaf6e661127f23ede1e4dde05d to your computer and use it in GitHub Desktop.
GCP IAM model diagram
digraph IAM {
rankdir="LR";
node [shape="component"];
subgraph cluster_iam {
cluster="true";
style="dashed";
label="IAM";
role [label="Role"];
perm [label="Permission"];
pol [label="Allow Policy",
URL="https://cloud.google.com/iam/docs/policies";
URL="https://cloud.google.com/resource-manager/reference/rest/Shared.Types/Policy";
];
binding;
condition;
}
subgraph cluster_members {
style="dashed";
label="Principals";
URL="https://cloud.google.com/iam/docs/principal-identifiers";
member [shape="box"];
sa [label="Service Account",
URL="https://cloud.google.com/iam/docs/service-account-overview";
];
member -> {
sa;
user;
} [dir="back", arrowtail="empty"];
}
subgraph svc {
cluster="true";
style="dashed";
label="Service";
res [label="Resource"];
}
subgraph composition {
edge [dir="back", arrowtail="diamond"];
pol -> binding -> {
role;
member;
/* optional */
condition;
};
role -> perm;
}
perm -> res [label="verb"];
subgraph cluster_resource_manager {
style="dashed";
label="Resource Manager";
parent [shape="box", label="container"];
parent -> {
project;
folder;
org;
} [dir="back", arrowtail="empty"];
subgraph hierarchy {
URL="https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy";
URL="https://cloud.google.com/iam/docs/resource-hierarchy-access-control";
org -> folder -> project -> res
[dir="back", arrowtail="diamond", label="contains"];
}
}
sa -> res [arrowhead="empty", label="is-a"];
res -> parent [arrowhead="empty", label="inherit"];
subgraph policy_bindings {
URL="https://cloud.google.com/iam/docs/manage-access-other-resources";
URL="https://cloud.google.com/resource-manager/reference/rest/Shared.Types/Binding";
edge [label="policy binding", dir="both"];
pol -> {
res;
parent;
};
}
}
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 8.0.5 (20230430.1635)
-->
<!-- Title: IAM Pages: 1 -->
<svg width="770pt" height="462pt"
viewBox="0.00 0.00 770.25 461.75" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 457.75)">
<title>IAM</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-457.75 766.25,-457.75 766.25,4 -4,4"/>
<g id="clust2" class="cluster">
<title>cluster_members</title>
<g id="a_clust2"><a xlink:href="https://cloud.google.com/iam/docs/principal-identifiers" xlink:title="Principals">
<polygon fill="none" stroke="black" stroke-dasharray="5,2" points="324.75,-282 324.75,-412 602.5,-412 602.5,-282 324.75,-282"/>
<text text-anchor="middle" x="463.62" y="-394.7" font-family="Times New Roman,serif" font-size="14.00">Principals</text>
</a>
</g>
</g>
<g id="clust4" class="cluster">
<title>svc</title>
<polygon fill="none" stroke="black" stroke-dasharray="5,2" points="669,-144 669,-220 754.25,-220 754.25,-144 669,-144"/>
<text text-anchor="middle" x="711.62" y="-202.7" font-family="Times New Roman,serif" font-size="14.00">Service</text>
</g>
<g id="clust1" class="cluster">
<title>cluster_iam</title>
<polygon fill="none" stroke="black" stroke-dasharray="5,2" points="8,-144 8,-274 586.75,-274 586.75,-144 8,-144"/>
<text text-anchor="middle" x="297.38" y="-256.7" font-family="Times New Roman,serif" font-size="14.00">IAM</text>
</g>
<g id="clust7" class="cluster">
<title>cluster_resource_manager</title>
<polygon fill="none" stroke="black" stroke-dasharray="5,2" points="211.5,-8 211.5,-124 747.12,-124 747.12,-8 211.5,-8"/>
<text text-anchor="middle" x="479.31" y="-106.7" font-family="Times New Roman,serif" font-size="14.00">Resource Manager</text>
</g>
<!-- role -->
<g id="node1" class="node">
<title>role</title>
<polygon fill="none" stroke="black" points="390.25,-188 336.25,-188 336.25,-184 332.25,-184 332.25,-180 336.25,-180 336.25,-160 332.25,-160 332.25,-156 336.25,-156 336.25,-152 390.25,-152 390.25,-188"/>
<polyline fill="none" stroke="black" points="336.25,-184 340.25,-184 340.25,-180 336.25,-180"/>
<polyline fill="none" stroke="black" points="336.25,-160 340.25,-160 340.25,-156 336.25,-156"/>
<text text-anchor="middle" x="363.25" y="-164.57" font-family="Times New Roman,serif" font-size="14.00">Role</text>
</g>
<!-- perm -->
<g id="node2" class="node">
<title>perm</title>
<polygon fill="none" stroke="black" points="578.75,-188 501.25,-188 501.25,-184 497.25,-184 497.25,-180 501.25,-180 501.25,-160 497.25,-160 497.25,-156 501.25,-156 501.25,-152 578.75,-152 578.75,-188"/>
<polyline fill="none" stroke="black" points="501.25,-184 505.25,-184 505.25,-180 501.25,-180"/>
<polyline fill="none" stroke="black" points="501.25,-160 505.25,-160 505.25,-156 501.25,-156"/>
<text text-anchor="middle" x="540" y="-164.57" font-family="Times New Roman,serif" font-size="14.00">Permission</text>
</g>
<!-- role&#45;&gt;perm -->
<g id="edge7" class="edge">
<title>role&#45;&gt;perm</title>
<path fill="none" stroke="black" d="M403.39,-170C432.54,-170 472.12,-170 501,-170"/>
<polygon fill="black" stroke="black" points="403.31,-170 397.31,-174 391.31,-170 397.31,-166 403.31,-170"/>
</g>
<!-- res -->
<g id="node9" class="node">
<title>res</title>
<polygon fill="none" stroke="black" points="746.25,-188 677,-188 677,-184 673,-184 673,-180 677,-180 677,-160 673,-160 673,-156 677,-156 677,-152 746.25,-152 746.25,-188"/>
<polyline fill="none" stroke="black" points="677,-184 681,-184 681,-180 677,-180"/>
<polyline fill="none" stroke="black" points="677,-160 681,-160 681,-156 677,-156"/>
<text text-anchor="middle" x="711.62" y="-164.57" font-family="Times New Roman,serif" font-size="14.00">Resource</text>
</g>
<!-- perm&#45;&gt;res -->
<g id="edge8" class="edge">
<title>perm&#45;&gt;res</title>
<path fill="none" stroke="black" d="M579.07,-170C604.82,-170 638.94,-170 665.98,-170"/>
<polygon fill="black" stroke="black" points="665.71,-173.5 675.71,-170 665.71,-166.5 665.71,-173.5"/>
<text text-anchor="middle" x="635.75" y="-172.45" font-family="Times New Roman,serif" font-size="14.00">verb</text>
</g>
<!-- pol -->
<g id="node3" class="node">
<title>pol</title>
<g id="a_node3"><a xlink:href="https://cloud.google.com/resource-manager/reference/rest/Shared.Types/Policy" xlink:title="Allow Policy">
<polygon fill="none" stroke="black" points="104,-242 16,-242 16,-238 12,-238 12,-234 16,-234 16,-214 12,-214 12,-210 16,-210 16,-206 104,-206 104,-242"/>
<polyline fill="none" stroke="black" points="16,-238 20,-238 20,-234 16,-234"/>
<polyline fill="none" stroke="black" points="16,-214 20,-214 20,-210 16,-210"/>
<text text-anchor="middle" x="60" y="-218.57" font-family="Times New Roman,serif" font-size="14.00">Allow Policy</text>
</a>
</g>
</g>
<!-- binding -->
<g id="node4" class="node">
<title>binding</title>
<polygon fill="none" stroke="black" points="281.62,-242 224.38,-242 224.38,-238 220.38,-238 220.38,-234 224.38,-234 224.38,-214 220.38,-214 220.38,-210 224.38,-210 224.38,-206 281.62,-206 281.62,-242"/>
<polyline fill="none" stroke="black" points="224.38,-238 228.38,-238 228.38,-234 224.38,-234"/>
<polyline fill="none" stroke="black" points="224.38,-214 228.38,-214 228.38,-210 224.38,-210"/>
<text text-anchor="middle" x="253" y="-218.57" font-family="Times New Roman,serif" font-size="14.00">binding</text>
</g>
<!-- pol&#45;&gt;binding -->
<g id="edge3" class="edge">
<title>pol&#45;&gt;binding</title>
<path fill="none" stroke="black" d="M117.32,-224C152.39,-224 196,-224 223.92,-224"/>
<polygon fill="black" stroke="black" points="117.24,-224 111.24,-228 105.24,-224 111.24,-220 117.24,-224"/>
</g>
<!-- pol&#45;&gt;res -->
<g id="edge17" class="edge">
<title>pol&#45;&gt;res</title>
<path fill="none" stroke="black" d="M70.89,-252.25C93.25,-310.38 153.55,-438 252,-438 252,-438 252,-438 541,-438 653.14,-438 694.21,-268.38 706.32,-199.03"/>
<polygon fill="black" stroke="black" points="73.93,-251.39 67.15,-243.25 67.37,-253.84 73.93,-251.39"/>
<polygon fill="black" stroke="black" points="709.89,-199.86 708.08,-189.42 702.99,-198.71 709.89,-199.86"/>
<text text-anchor="middle" x="363.25" y="-440.45" font-family="Times New Roman,serif" font-size="14.00">policy binding</text>
</g>
<!-- parent -->
<g id="node10" class="node">
<title>parent</title>
<polygon fill="none" stroke="black" points="286.5,-92 219.5,-92 219.5,-56 286.5,-56 286.5,-92"/>
<text text-anchor="middle" x="253" y="-68.58" font-family="Times New Roman,serif" font-size="14.00">container</text>
</g>
<!-- pol&#45;&gt;parent -->
<g id="edge18" class="edge">
<title>pol&#45;&gt;parent</title>
<path fill="none" stroke="black" d="M92.66,-199.14C127.97,-171.4 184.79,-126.78 220.18,-98.99"/>
<polygon fill="black" stroke="black" points="91.12,-196.68 85.42,-205.61 95.45,-202.18 91.12,-196.68"/>
<polygon fill="black" stroke="black" points="221.98,-101.24 227.69,-92.31 217.66,-95.73 221.98,-101.24"/>
<text text-anchor="middle" x="161.75" y="-177.45" font-family="Times New Roman,serif" font-size="14.00">policy binding</text>
</g>
<!-- binding&#45;&gt;role -->
<g id="edge4" class="edge">
<title>binding&#45;&gt;role</title>
<path fill="none" stroke="black" d="M293.35,-204.37C307.52,-197.3 323.16,-189.5 335.96,-183.12"/>
<polygon fill="black" stroke="black" points="293.42,-204.33 289.84,-210.59 282.68,-209.69 286.27,-203.43 293.42,-204.33"/>
</g>
<!-- condition -->
<g id="node5" class="node">
<title>condition</title>
<polygon fill="none" stroke="black" points="397.5,-242 329,-242 329,-238 325,-238 325,-234 329,-234 329,-214 325,-214 325,-210 329,-210 329,-206 397.5,-206 397.5,-242"/>
<polyline fill="none" stroke="black" points="329,-238 333,-238 333,-234 329,-234"/>
<polyline fill="none" stroke="black" points="329,-214 333,-214 333,-210 329,-210"/>
<text text-anchor="middle" x="363.25" y="-218.57" font-family="Times New Roman,serif" font-size="14.00">condition</text>
</g>
<!-- binding&#45;&gt;condition -->
<g id="edge5" class="edge">
<title>binding&#45;&gt;condition</title>
<path fill="none" stroke="black" d="M294.56,-224C305.81,-224 317.88,-224 328.68,-224"/>
<polygon fill="black" stroke="black" points="294.78,-224 288.78,-228 282.78,-224 288.78,-220 294.78,-224"/>
</g>
<!-- member -->
<g id="node6" class="node">
<title>member</title>
<polygon fill="none" stroke="black" points="393.75,-326 332.75,-326 332.75,-290 393.75,-290 393.75,-326"/>
<text text-anchor="middle" x="363.25" y="-302.57" font-family="Times New Roman,serif" font-size="14.00">member</text>
</g>
<!-- binding&#45;&gt;member -->
<g id="edge6" class="edge">
<title>binding&#45;&gt;member</title>
<path fill="none" stroke="black" d="M287.49,-250.04C298.91,-258.92 311.76,-268.89 323.5,-278 328.34,-281.75 333.52,-285.77 338.47,-289.6"/>
<polygon fill="black" stroke="black" points="287.66,-250.17 280.47,-249.65 278.19,-242.81 285.38,-243.33 287.66,-250.17"/>
</g>
<!-- sa -->
<g id="node7" class="node">
<title>sa</title>
<g id="a_node7"><a xlink:href="https://cloud.google.com/iam/docs/service-account-overview" xlink:title="Service Account">
<polygon fill="none" stroke="black" points="594.5,-326 485.5,-326 485.5,-322 481.5,-322 481.5,-318 485.5,-318 485.5,-298 481.5,-298 481.5,-294 485.5,-294 485.5,-290 594.5,-290 594.5,-326"/>
<polyline fill="none" stroke="black" points="485.5,-322 489.5,-322 489.5,-318 485.5,-318"/>
<polyline fill="none" stroke="black" points="485.5,-298 489.5,-298 489.5,-294 485.5,-294"/>
<text text-anchor="middle" x="540" y="-302.57" font-family="Times New Roman,serif" font-size="14.00">Service Account</text>
</a>
</g>
</g>
<!-- member&#45;&gt;sa -->
<g id="edge1" class="edge">
<title>member&#45;&gt;sa</title>
<path fill="none" stroke="black" d="M404.71,-308C428.63,-308 459.21,-308 485.14,-308"/>
<polygon fill="none" stroke="black" points="404.89,-304.5 394.89,-308 404.89,-311.5 404.89,-304.5"/>
</g>
<!-- user -->
<g id="node8" class="node">
<title>user</title>
<polygon fill="none" stroke="black" points="567,-380 513,-380 513,-376 509,-376 509,-372 513,-372 513,-352 509,-352 509,-348 513,-348 513,-344 567,-344 567,-380"/>
<polyline fill="none" stroke="black" points="513,-376 517,-376 517,-372 513,-372"/>
<polyline fill="none" stroke="black" points="513,-352 517,-352 517,-348 513,-348"/>
<text text-anchor="middle" x="540" y="-356.57" font-family="Times New Roman,serif" font-size="14.00">user</text>
</g>
<!-- member&#45;&gt;user -->
<g id="edge2" class="edge">
<title>member&#45;&gt;user</title>
<path fill="none" stroke="black" d="M404.19,-320.34C437.45,-330.62 483.87,-344.96 512.65,-353.86"/>
<polygon fill="none" stroke="black" points="405.48,-316.77 394.89,-317.16 403.41,-323.46 405.48,-316.77"/>
</g>
<!-- sa&#45;&gt;res -->
<g id="edge15" class="edge">
<title>sa&#45;&gt;res</title>
<path fill="none" stroke="black" d="M583.42,-289.62C590.02,-286.11 596.6,-282.21 602.5,-278 635.79,-254.27 668.17,-219.98 688.68,-196.44"/>
<polygon fill="none" stroke="black" points="691.82,-199.16 695.68,-189.29 686.51,-194.6 691.82,-199.16"/>
<text text-anchor="middle" x="635.75" y="-270.45" font-family="Times New Roman,serif" font-size="14.00">is&#45;a</text>
</g>
<!-- res&#45;&gt;parent -->
<g id="edge16" class="edge">
<title>res&#45;&gt;parent</title>
<path fill="none" stroke="black" d="M676.82,-159.38C655.64,-153.04 627.68,-145.23 602.5,-140 479.91,-114.54 444.67,-132.55 323.5,-101 314.68,-98.7 305.45,-95.63 296.7,-92.37"/>
<polygon fill="none" stroke="black" points="298.3,-88.85 287.71,-88.51 295.78,-95.38 298.3,-88.85"/>
<text text-anchor="middle" x="444.25" y="-125.45" font-family="Times New Roman,serif" font-size="14.00">inherit</text>
</g>
<!-- project -->
<g id="node11" class="node">
<title>project</title>
<polygon fill="none" stroke="black" points="739.12,-79 684.12,-79 684.12,-75 680.12,-75 680.12,-71 684.12,-71 684.12,-51 680.12,-51 680.12,-47 684.12,-47 684.12,-43 739.12,-43 739.12,-79"/>
<polyline fill="none" stroke="black" points="684.12,-75 688.12,-75 688.12,-71 684.12,-71"/>
<polyline fill="none" stroke="black" points="684.12,-51 688.12,-51 688.12,-47 684.12,-47"/>
<text text-anchor="middle" x="711.62" y="-55.58" font-family="Times New Roman,serif" font-size="14.00">project</text>
</g>
<!-- parent&#45;&gt;project -->
<g id="edge9" class="edge">
<title>parent&#45;&gt;project</title>
<path fill="none" stroke="black" d="M291.81,-50.51C301.77,-45.43 312.74,-40.76 323.5,-38 443.62,-7.16 479.41,-18.86 602.5,-34 630.73,-37.47 662.19,-45.86 683.86,-52.37"/>
<polygon fill="none" stroke="black" points="290.38,-47.84 283.24,-55.67 293.7,-54 290.38,-47.84"/>
</g>
<!-- folder -->
<g id="node12" class="node">
<title>folder</title>
<polygon fill="none" stroke="black" points="567,-79 513,-79 513,-75 509,-75 509,-71 513,-71 513,-51 509,-51 509,-47 513,-47 513,-43 567,-43 567,-79"/>
<polyline fill="none" stroke="black" points="513,-75 517,-75 517,-71 513,-71"/>
<polyline fill="none" stroke="black" points="513,-51 517,-51 517,-47 513,-47"/>
<text text-anchor="middle" x="540" y="-55.58" font-family="Times New Roman,serif" font-size="14.00">folder</text>
</g>
<!-- parent&#45;&gt;folder -->
<g id="edge10" class="edge">
<title>parent&#45;&gt;folder</title>
<path fill="none" stroke="black" d="M297.04,-54.46C305.64,-51.36 314.73,-48.64 323.5,-47 390.75,-34.4 471.64,-46.88 512.54,-55.08"/>
<polygon fill="none" stroke="black" points="295.93,-51.52 287.84,-58.37 298.44,-58.05 295.93,-51.52"/>
</g>
<!-- org -->
<g id="node13" class="node">
<title>org</title>
<polygon fill="none" stroke="black" points="390.25,-92 336.25,-92 336.25,-88 332.25,-88 332.25,-84 336.25,-84 336.25,-64 332.25,-64 332.25,-60 336.25,-60 336.25,-56 390.25,-56 390.25,-92"/>
<polyline fill="none" stroke="black" points="336.25,-88 340.25,-88 340.25,-84 336.25,-84"/>
<polyline fill="none" stroke="black" points="336.25,-64 340.25,-64 340.25,-60 336.25,-60"/>
<text text-anchor="middle" x="363.25" y="-68.58" font-family="Times New Roman,serif" font-size="14.00">org</text>
</g>
<!-- parent&#45;&gt;org -->
<g id="edge11" class="edge">
<title>parent&#45;&gt;org</title>
<path fill="none" stroke="black" d="M297.4,-74C310.38,-74 324.22,-74 335.76,-74"/>
<polygon fill="none" stroke="black" points="297.77,-70.5 287.77,-74 297.77,-77.5 297.77,-70.5"/>
</g>
<!-- project&#45;&gt;res -->
<g id="edge14" class="edge">
<title>project&#45;&gt;res</title>
<path fill="none" stroke="black" d="M711.62,-92.49C711.62,-111.72 711.62,-135.64 711.62,-151.78"/>
<polygon fill="black" stroke="black" points="711.63,-92.39 707.63,-86.39 711.63,-80.39 715.63,-86.39 711.63,-92.39"/>
<text text-anchor="middle" x="700.75" y="-110.08" font-family="Times New Roman,serif" font-size="14.00">contains</text>
</g>
<!-- folder&#45;&gt;project -->
<g id="edge13" class="edge">
<title>folder&#45;&gt;project</title>
<path fill="none" stroke="black" d="M579.94,-61C611.77,-61 655.94,-61 683.9,-61"/>
<polygon fill="black" stroke="black" points="580.03,-61 574.03,-65 568.03,-61 574.03,-57 580.03,-61"/>
<text text-anchor="middle" x="635.75" y="-63.45" font-family="Times New Roman,serif" font-size="14.00">contains</text>
</g>
<!-- org&#45;&gt;folder -->
<g id="edge12" class="edge">
<title>org&#45;&gt;folder</title>
<path fill="none" stroke="black" d="M403.32,-71.09C436.64,-68.61 483.63,-65.12 512.66,-62.96"/>
<polygon fill="black" stroke="black" points="403.28,-71.1 397.59,-75.53 391.31,-71.99 397,-67.55 403.28,-71.1"/>
<text text-anchor="middle" x="444.25" y="-72.45" font-family="Times New Roman,serif" font-size="14.00">contains</text>
</g>
</g>
</svg>
@Wintus
Copy link
Author

Wintus commented Jun 6, 2023

rendered

GCP-IAM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment