<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Rbac</title><link>https://www.pulumi.com/blog/tag/rbac/</link><description>Pulumi blog posts: Rbac.</description><language>en-us</language><pubDate>Thu, 19 Mar 2026 10:30:00 -0700</pubDate><item><title>Pulumi IAM Expands: Manage Access at Scale with Tags, Roles, and Teams</title><link>https://www.pulumi.com/blog/expanding-pulumi-iam-custom-permissions/</link><pubDate>Thu, 19 Mar 2026 10:30:00 -0700</pubDate><guid>https://www.pulumi.com/blog/expanding-pulumi-iam-custom-permissions/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/expanding-pulumi-iam-custom-permissions/index.png" /&gt;
&lt;p&gt;Since the launch of &lt;a href="https://www.pulumi.com/blog/pulumi-cloud-iam-launch/"&gt;Pulumi IAM&lt;/a&gt; with &lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/roles/"&gt;custom roles&lt;/a&gt; and scoped &lt;a href="https://www.pulumi.com/docs/administration/access-identity/access-tokens/"&gt;access tokens&lt;/a&gt;, organizations have been using fine-grained permissions to secure their automation and CI/CD pipelines. As teams scale to hundreds or thousands of stacks, environments, and accounts, the next challenge is applying those permissions efficiently.&lt;/p&gt;
&lt;p&gt;Today, we&amp;rsquo;re introducing three new capabilities to help you manage permissions more dynamically at scale: &lt;strong&gt;tag-based access control&lt;/strong&gt;, &lt;strong&gt;team role assignments&lt;/strong&gt;, and &lt;strong&gt;user role assignments&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="why-tag-based-access-control"&gt;Why tag-based access control?&lt;/h2&gt;
&lt;p&gt;With custom roles, you can define granular permissions using &lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/scopes"&gt;fine-grained scopes&lt;/a&gt;. However, applying those roles still requires selecting individual stacks, environments, or accounts one by one. For organizations managing a large number of Pulumi entities, this means either granting overly broad access or spending significant time on manual configuration. Tag-based access control solves this problem.&lt;/p&gt;
&lt;h2 id="whats-new"&gt;What&amp;rsquo;s new?&lt;/h2&gt;
&lt;h3 id="tag-based-access-control"&gt;Tag-based access control&lt;/h3&gt;
&lt;p&gt;You can now create rules within a custom role that dynamically grant permissions based on entity tags. This works across IaC stacks, ESC environments, and Insights accounts. For example, when a new stack is created and tagged &lt;code&gt;env:prod&lt;/code&gt;, anyone with a role containing a matching tag-based rule automatically gets the right permissions. No manual assignment required.&lt;/p&gt;
&lt;p&gt;A single role can include multiple tag-based rules, and they are evaluated with &lt;strong&gt;OR&lt;/strong&gt; logic. If an entity matches any of the rules, the permissions are granted. Within a single rule, you can combine multiple key-value conditions with implicit &lt;strong&gt;AND&lt;/strong&gt; logic for precise targeting. For example, a rule with conditions &lt;code&gt;env:prod&lt;/code&gt; and &lt;code&gt;team:payments&lt;/code&gt; ensures access is granted only to production resources owned by the payments team.&lt;/p&gt;
&lt;h3 id="team-role-assignments"&gt;Team role assignments&lt;/h3&gt;
&lt;p&gt;Custom roles can now be assigned directly to &lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/teams"&gt;teams&lt;/a&gt; within your Pulumi organization. When an engineer joins a team, whether manually or via &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/scim/"&gt;SCIM provisioning&lt;/a&gt;, they automatically inherit the permissions defined in the team&amp;rsquo;s assigned roles.&lt;/p&gt;
&lt;p&gt;Teams support both &lt;strong&gt;inline permissions&lt;/strong&gt; (ad-hoc access to specific stacks, environments, or accounts) and &lt;strong&gt;role-based permissions&lt;/strong&gt; simultaneously. You can assign &lt;strong&gt;multiple roles&lt;/strong&gt; to a single team, giving you full flexibility to compose access from reusable building blocks while retaining the ability to grant one-off access where needed. If you have existing workflows built around ad-hoc assignments to teams, those continue to work exactly as before. You can adopt roles incrementally or mix both approaches on the same team.&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Team admins (or users with the &lt;code&gt;team:update&lt;/code&gt; scope) can continue to manage their team&amp;rsquo;s inline permissions as they do today. However, assigning organization-level custom roles to a team requires additional permissions: &lt;code&gt;role:read&lt;/code&gt; and &lt;code&gt;role:update&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="user-role-assignments"&gt;User role assignments&lt;/h3&gt;
&lt;p&gt;Custom roles can also be assigned directly to individual organization members. This is useful for users whose responsibilities span multiple teams or require permissions beyond the existing org-level &lt;code&gt;Admin&lt;/code&gt;, &lt;code&gt;Member&lt;/code&gt;, and &lt;code&gt;Billing Manager&lt;/code&gt; &lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/roles"&gt;roles&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="how-permissions-work-together"&gt;How permissions work together&lt;/h3&gt;
&lt;p&gt;Permissions in Pulumi IAM are &lt;strong&gt;additive&lt;/strong&gt;. A user receives the union of all permissions granted to them, including permissions from roles assigned directly to them as a user and permissions from roles assigned to any team they belong to. A user on both the &amp;ldquo;SRE&amp;rdquo; and &amp;ldquo;Security&amp;rdquo; teams inherits permissions from both team roles, plus any role assigned to them individually.&lt;/p&gt;
&lt;h2 id="how-to-get-started"&gt;How to get started&lt;/h2&gt;
&lt;p&gt;Configuring tag-based access control and role assignments is done through the Pulumi Cloud console and REST API.&lt;/p&gt;
&lt;h3 id="1-create-a-custom-role-with-tag-based-rules"&gt;1. Create a custom role with tag-based rules&lt;/h3&gt;
&lt;p&gt;In Pulumi Cloud, navigate to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Access Management&lt;/strong&gt; &amp;gt; &lt;strong&gt;Roles&lt;/strong&gt; and create a new custom role. In the role configuration, add tag-based rules that define which entities the role should apply to.&lt;/p&gt;
&lt;p&gt;For example, to create a role that grants write access to all production stacks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Create custom role&lt;/strong&gt; and give it a descriptive name (e.g., &amp;ldquo;Production Deployer&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;Add a permission set (e.g., Stack Write) to the role&lt;/li&gt;
&lt;li&gt;Under entity selection, choose &lt;strong&gt;Tag-based rule&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Set the condition: tag key &lt;code&gt;env&lt;/code&gt; equals &lt;code&gt;prod&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save the role&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="2-assign-the-role-to-a-team"&gt;2. Assign the role to a team&lt;/h3&gt;
&lt;p&gt;Go to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Access Management&lt;/strong&gt; &amp;gt; &lt;strong&gt;Teams&lt;/strong&gt;, select a team, and assign your custom role. All team members immediately inherit the defined permissions.&lt;/p&gt;
&lt;h3 id="3-assign-a-role-to-an-individual-user"&gt;3. Assign a role to an individual user&lt;/h3&gt;
&lt;p&gt;For users with unique access requirements, go to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Access Management&lt;/strong&gt; &amp;gt; &lt;strong&gt;Members&lt;/strong&gt;, select a user, and assign a custom role directly.&lt;/p&gt;
&lt;div class="my-4"&gt;
&lt;video class="flex outline-none rounded-lg w-full" title="Custom roles with tag-based access control"
controls
autoplay muted playsinline
loop &gt;
&lt;source src="abac-demo.mp4" /&gt;
&lt;/video&gt;
&lt;/div&gt;
&lt;h2 id="enforce-tagging-standards-with-pulumi-policy"&gt;Enforce tagging standards with Pulumi Policy&lt;/h2&gt;
&lt;p&gt;Tag-based access control relies on consistent tagging. If a stack is missing a tag or has an incorrect value, permissions won&amp;rsquo;t be applied as expected. &lt;a href="https://www.pulumi.com/docs/insights/policy/"&gt;Pulumi Policy&lt;/a&gt; closes this gap by letting you enforce tagging standards as a &lt;a href="https://www.pulumi.com/docs/insights/policy/policy-groups/"&gt;preventative policy group&lt;/a&gt;, so any &lt;code&gt;pulumi up&lt;/code&gt; on a stack with missing or invalid tags is blocked before deployment. This ensures your tag-based RBAC rules always grant the correct permissions. Policy enforces the standard, RBAC enforces the access.&lt;/p&gt;
&lt;p&gt;To learn how to write policies that validate stack tags, see &lt;a href="https://www.pulumi.com/docs/insights/policy/policy-packs/authoring/#using-stack-tags-in-policies"&gt;Using stack tags in policies&lt;/a&gt;.&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Pulumi Policy currently supports tag enforcement for IaC stacks. For ESC environments and Insights accounts, tags are managed through the Pulumi Cloud console or REST API.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="availability"&gt;Availability&lt;/h2&gt;
&lt;p&gt;Tag-based access control, team role assignments, and user role assignments are available today for customers on the &lt;strong&gt;Pulumi Enterprise&lt;/strong&gt; and &lt;strong&gt;Pulumi Business Critical&lt;/strong&gt; plans. Check out our &lt;a href="https://www.pulumi.com/pricing/"&gt;pricing page&lt;/a&gt; for more details on editions and what&amp;rsquo;s included.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With custom roles providing fine-grained permissions, tag-based rules enabling dynamic access policies, and the ability to assign roles directly to teams and users, Pulumi IAM now provides everything you need to implement automated, least-privilege access control at scale. We&amp;rsquo;re excited to see how you leverage these new capabilities to secure and streamline your cloud operations.&lt;/p&gt;
&lt;p&gt;Explore the &lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac"&gt;IAM documentation&lt;/a&gt; to get started, and share your feedback in our &lt;a href="https://github.com/pulumi/pulumi-cloud-requests/issues"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="learn-more"&gt;Learn more&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac"&gt;RBAC overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/roles"&gt;Roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/permission-sets"&gt;Permission sets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/teams"&gt;Teams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/administration/access-identity/rbac/scopes"&gt;Scopes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-cloud-iam-launch/"&gt;Pulumi IAM launch blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-cloud-iam-self-hosted/"&gt;Pulumi IAM for self-hosted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>Devon Grove</author><author>Davide Massarenti</author><author>Casey Huang</author><author>Arun Loganathan</author><category>iam</category><category>rbac</category><category>security</category><category>features</category><category>pulumi-cloud</category></item><item><title>Pulumi IAM Now Available for Self-Hosted Pulumi Cloud</title><link>https://www.pulumi.com/blog/pulumi-cloud-iam-self-hosted/</link><pubDate>Wed, 14 Jan 2026 11:18:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumi-cloud-iam-self-hosted/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-cloud-iam-self-hosted/index.png" /&gt;
&lt;p&gt;We&amp;rsquo;re excited to announce that &lt;strong&gt;Pulumi Identity and Access Management (IAM)&lt;/strong&gt; is now available for self-hosted instances of Pulumi Cloud. This foundational security capability brings the same &lt;a href="https://www.pulumi.com/blog/pulumi-cloud-iam-launch/"&gt;enterprise-grade access management&lt;/a&gt; we launched for Pulumi Cloud SaaS to organizations running Pulumi on their own infrastructure.&lt;/p&gt;
&lt;h2 id="enterprise-security-for-self-hosted-deployments"&gt;Enterprise Security for Self-Hosted Deployments&lt;/h2&gt;
&lt;p&gt;Self-hosted Pulumi Cloud customers can now leverage the full power of &lt;strong&gt;Custom Roles&lt;/strong&gt; and &lt;strong&gt;Granular Access Tokens&lt;/strong&gt; to implement Zero Trust security principles and least privilege access controls within their own environments. This means you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Define Custom Permissions&lt;/strong&gt; with fine-grained scopes (e.g., &lt;code&gt;stack:delete&lt;/code&gt;, &lt;code&gt;environment:read&lt;/code&gt;) tailored to your organization&amp;rsquo;s security requirements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create Custom Roles&lt;/strong&gt; by combining these permissions with specific Pulumi entities (Stacks, Environments, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generate Scoped Organization Access Tokens&lt;/strong&gt; that are precisely limited to the permissions defined in their associated roles, dramatically reducing the blast radius if credentials are compromised.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="secure-automation-for-on-premises-infrastructure"&gt;Secure Automation for On-Premises Infrastructure&lt;/h2&gt;
&lt;p&gt;This release is powerful for self-hosted Pulumi Cloud deployments where security and compliance requirements are often even more stringent. You can now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Implement Least Privilege CI/CD:&lt;/strong&gt; Scope pipeline tokens to only the actions and resources they absolutely need, ensuring your automation follows the same security standards as your infrastructure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhance Compliance Posture:&lt;/strong&gt; Demonstrate precise, auditable control over programmatic access to auditors and security teams.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduce Operational Risk:&lt;/strong&gt; Limit the potential impact of compromised tokens by restricting them to specific roles and permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Self-hosted customers can access IAM features through the same intuitive interface available in Pulumi Cloud SaaS. Navigate to &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Access Management&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Roles&lt;/strong&gt; to begin creating Custom Permissions and Custom Roles, then generate scoped Organization Access Tokens from &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Access Management&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Access Tokens&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For detailed information about Pulumi IAM capabilities, including step-by-step guides and best practices, see our &lt;a href="https://www.pulumi.com/blog/pulumi-cloud-iam-launch/"&gt;comprehensive announcement blog post&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="learn-more"&gt;Learn More&lt;/h2&gt;
&lt;p&gt;Explore the IAM &amp;amp; RBAC documentation to get started:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/roles"&gt;Roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/permissions"&gt;Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/scopes"&gt;Scopes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;re committed to bringing enterprise-grade security features to all Pulumi deployments, whether in the cloud or on-premises. If you have questions or feedback, please reach out through your account representative or our &lt;a href="https://github.com/pulumi/pulumi-cloud-requests/issues"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;</description><author>Davide Massarenti</author><author>Devon Grove</author><author>Casey Huang</author><author>Arun Loganathan</author><category>iam</category><category>rbac</category><category>security</category><category>features</category><category>pulumi-cloud</category><category>access-tokens</category><category>self-hosted</category></item><item><title>Announcing Pulumi Identity and Access Management (IAM)</title><link>https://www.pulumi.com/blog/pulumi-cloud-iam-launch/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumi-cloud-iam-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-cloud-iam-launch/index.png" /&gt;
&lt;p&gt;Cloud development is accelerating at an unprecedented pace, fueled by AI and the relentless drive for innovation. But this incredible speed demands unwavering trust in your security posture. How do you empower teams to deploy rapidly and frequently without opening doors to risk or violating compliance mandates? Today, we&amp;rsquo;re thrilled to answer that critical challenge by introducing &lt;strong&gt;Pulumi Identity and Access Management&lt;/strong&gt; (IAM) – a foundational new capability designed to embed robust, granular security directly into your cloud development lifecycle, enabling you to innovate both quickly and safely with Pulumi. Pulumi IAM provides the unified framework for fine-grained authorization needed to confidently manage modern cloud infrastructure and applications across the entire Pulumi Cloud platform.&lt;/p&gt;
&lt;h2 id="our-vision-for-pulumi-iam"&gt;Our Vision for Pulumi IAM&lt;/h2&gt;
&lt;p&gt;Pulumi IAM is a foundational investment, delivering enterprise-grade access management through a phased approach. Today&amp;rsquo;s release marks the beginning, with much more planned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Phase 1: Granular Access Tokens &amp;amp; Custom Roles (Available Today)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Define custom, reusable &lt;strong&gt;Permissions&lt;/strong&gt; with &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/scopes"&gt;fine-grained scopes&lt;/a&gt; (e.g., &lt;code&gt;stack:delete&lt;/code&gt; only).&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;Custom Roles&lt;/strong&gt; by combining Permissions with specific Pulumi Entities (Stacks, Environments, etc.).&lt;/li&gt;
&lt;li&gt;Generate &lt;strong&gt;Organization Access Tokens&lt;/strong&gt; scoped precisely to these Custom Roles, perfect for secure automation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Phase 2: User &amp;amp; Team Role Assignment (Coming Soon)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Leverage &lt;strong&gt;OIDC configuration&lt;/strong&gt; to dynamically assume Custom Roles for secure, tokenless authentication from CI/CD systems like GitHub Actions, GitLab, and more.&lt;/li&gt;
&lt;li&gt;Assign these powerful Custom Roles directly to &lt;strong&gt;individual users and teams&lt;/strong&gt; within your Pulumi organization.&lt;/li&gt;
&lt;li&gt;Implement a complete overhaul of user and team access management, moving beyond the basic &lt;code&gt;Admin&lt;/code&gt;/&lt;code&gt;Member&lt;/code&gt; distinctions, and enabling reusability of custom building blocks permissions and roles that work for your organization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Phase 3: Advanced Authorization &amp;amp; Scalability (Future Release)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduce &lt;strong&gt;Attribute-Based Access Control (ABAC)&lt;/strong&gt;, allowing policies based on tags or other attributes of Pulumi Entities (e.g., &amp;ldquo;grant &amp;lsquo;dev-role&amp;rsquo; access to all stacks tagged &amp;rsquo;env:dev&amp;rsquo;&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;Enable the creation of &lt;strong&gt;Custom RBAC Policies&lt;/strong&gt; with conditional logic for highly specific access scenarios and reuse them&lt;/li&gt;
&lt;li&gt;Provide mechanisms to manage permissions across hundreds or thousands of Pulumi Entities efficiently.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="a-foundation-for-zero-trust--unified-security"&gt;A Foundation for Zero Trust &amp;amp; Unified Security&lt;/h2&gt;
&lt;p&gt;Pulumi IAM isn&amp;rsquo;t just another feature; it&amp;rsquo;s a foundational pillar underpinning security across the entire Pulumi Cloud ecosystem, enabling organizations to implement &lt;strong&gt;Zero Trust&lt;/strong&gt; principles for their infrastructure management. Modern security models assume breaches will happen and demand rigorous verification for every access request. Static, organization-wide roles no longer suffice where separation of duties, least privilege, and compliance are paramount.&lt;/p&gt;
&lt;p&gt;Pulumi IAM addresses these challenges by providing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Least Privilege Enforcement:&lt;/strong&gt; Define precisely &lt;em&gt;who&lt;/em&gt; can do &lt;em&gt;what&lt;/em&gt; on &lt;em&gt;which&lt;/em&gt; specific resources, minimizing the potential impact if credentials or accounts are compromised. This is core to Zero Trust – grant only the minimum necessary access, verified at the point of action.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Granular Control Across Pulumi:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure as Code (IaC):&lt;/strong&gt; Apply fine-grained controls over Pulumi Stacks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secrets Management:&lt;/strong&gt; Define specific access levels for Pulumi ESC Environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Insights:&lt;/strong&gt; Manage permissions for Pulumi Insights account settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure Automation:&lt;/strong&gt; Provide secure, least-privilege tokens and OIDC integration for CI/CD pipelines and automation, drastically reducing the risk associated with over-privileged service accounts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unified, Scalable Governance:&lt;/strong&gt; Establish a consistent authorization model that simplifies administration and scales from small teams to complex enterprise environments, ensuring security doesn&amp;rsquo;t hinder velocity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="launching-today-granular-access-tokens-via-custom-roles"&gt;Launching Today: Granular Access Tokens via Custom Roles&lt;/h2&gt;
&lt;p&gt;This vision begins today with the initial phase of Pulumi IAM, enabling you to define &lt;strong&gt;Custom Roles&lt;/strong&gt; built from &lt;strong&gt;fine-grained Permissions&lt;/strong&gt; and apply them specifically to &lt;strong&gt;Organization Access Tokens&lt;/strong&gt;. This initial step provides immediate, significant security benefits, particularly for automation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;True Least Privilege for CI/CD:&lt;/strong&gt; Scope pipeline tokens to &lt;em&gt;only&lt;/em&gt; the actions (e.g., &lt;code&gt;pulumi up&lt;/code&gt;) and Entities (e.g., &lt;code&gt;stack: myapp-prod&lt;/code&gt;) they absolutely need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduced Blast Radius:&lt;/strong&gt; If a scoped token is compromised, the potential damage is limited strictly to the permissions defined in its associated role.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Compliance:&lt;/strong&gt; Demonstrate precise control over programmatic access to auditors.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-to-get-started-with-granular-access-tokens"&gt;How to Get Started with Granular Access Tokens&lt;/h2&gt;
&lt;p&gt;Configuring and using Custom Roles for scoped tokens is done via the Pulumi Cloud console:&lt;/p&gt;
&lt;h3 id="1-define-a-custom-permission-optional"&gt;1. Define a Custom Permission (Optional)&lt;/h3&gt;
&lt;p&gt;Create reusable sets of fine-grained scopes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As an admin, navigate to Organization Settings -&amp;gt; Roles -&amp;gt; Permissions&lt;/li&gt;
&lt;li&gt;Follow instructions for &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/permissions#creating-custom-permissions"&gt;creating a custom permission&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-create-a-custom-role"&gt;2. Create a Custom Role&lt;/h3&gt;
&lt;p&gt;Combine permissions with specific resources.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As an admin, navigate to Organization Settings -&amp;gt; Roles&lt;/li&gt;
&lt;li&gt;Follow instructions for &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/roles#creating-custom-roles"&gt;creating a custom role&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-generate-a-scoped-organization-access-token"&gt;3. Generate a Scoped Organization Access Token&lt;/h3&gt;
&lt;p&gt;Generate an organization access token with narrowed scope.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As an admin, navigate to Organization Settings -&amp;gt; Access Tokens -&amp;gt; Organization Access Tokens.*&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Create token&amp;rdquo;. Provide a description. &lt;strong&gt;Select your Custom Role&lt;/strong&gt; from the &amp;ldquo;Role&amp;rdquo; dropdown. Generate the token.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="new-scenarios-unlocked-today"&gt;New Scenarios Unlocked Today&lt;/h2&gt;
&lt;p&gt;This release immediately enables more secure and compliant workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secure Multi-Environment CI/CD:&lt;/strong&gt; A single pipeline can use different tokens based on the target environment (dev, staging, prod), each assuming a role with appropriately restricted permissions (e.g., read-only for prod dependencies, write for the target stack).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restricted Operational Scripts:&lt;/strong&gt; An automation script designed only to read audit logs can use a token tied to a role granting &lt;em&gt;only&lt;/em&gt; &lt;code&gt;audit_log:read&lt;/code&gt; permission, preventing accidental or malicious modifications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safer ChatOps &amp;amp; Tooling:&lt;/strong&gt; Integrations like ChatOps bots can operate with tokens scoped down to only necessary actions (e.g., triggering a &lt;code&gt;pulumi preview&lt;/code&gt; on specific stacks).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;strong&gt;Available Today:&lt;/strong&gt; Custom Permissions, Custom Roles, and the ability to scope Organization Access Tokens using these roles, is &lt;strong&gt;available now&lt;/strong&gt; for customers on the &lt;strong&gt;Pulumi Enterprise&lt;/strong&gt; and &lt;strong&gt;Pulumi Business Critical&lt;/strong&gt; tiers. Explore these features in your Pulumi Cloud organization settings!&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="conclusion-building-a-more-secure-future"&gt;Conclusion: Building a More Secure Future&lt;/h2&gt;
&lt;p&gt;Pulumi Identity and Access Management (IAM) represents a fundamental advancement in securing cloud development lifecycles managed by Pulumi, providing the controls needed to confidently embrace speed and scale. Today’s launch of Granular Access Tokens via Custom Roles provides immediate security improvements for automation and programmatic access, laying the vital groundwork for our comprehensive IAM vision rooted in Zero Trust principles.&lt;/p&gt;
&lt;p&gt;This empowers platform and security teams with the fine-grained control needed to implement least privilege, enhance compliance, and scale Pulumi usage securely without sacrificing velocity.&lt;/p&gt;
&lt;p&gt;We encourage our Enterprise and Business Critical customers to explore Custom Roles and Granular Access Tokens today. Dive into the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac"&gt;documentation&lt;/a&gt; and start building roles tailored to your security requirements. We welcome your feedback and feature requests in our &lt;a href="https://github.com/pulumi/pulumi-cloud-requests/issues"&gt;GitHub repository&lt;/a&gt;. Join us as we build a more secure foundation for cloud engineering!&lt;/p&gt;
&lt;h2 id="learn-more"&gt;Learn More&lt;/h2&gt;
&lt;p&gt;Learn more about Pulumi Cloud&amp;rsquo;s new IAM &amp;amp; RBAC features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/roles"&gt;Roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/permissions"&gt;Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/rbac/scopes"&gt;Scopes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>Germán Lena</author><author>Devon Grove</author><author>Arun Loganathan</author><category>iam</category><category>rbac</category><category>security</category><category>features</category><category>pulumi-cloud</category><category>access-tokens</category><category>oidc</category></item><item><title>IaC Best Practices: Implementing RBAC and Security</title><link>https://www.pulumi.com/blog/iac-best-practices-implementing-rbac-and-security/</link><pubDate>Tue, 23 May 2023 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/iac-best-practices-implementing-rbac-and-security/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/iac-best-practices-implementing-rbac-and-security/index.png" /&gt;
&lt;p&gt;This post continues our series of blog posts focused on IaC best practices. In earlier posts, we introduced Zephyr Archaeotech Emporium, the fictional company that sits at the center of this series, and discussed Zephyr&amp;rsquo;s primary use case for Pulumi: managing their online retail store. You read how Zephyr&amp;rsquo;s initial use of Pulumi changed to incorporate the use of short-lived per-developer stacks. Later, as Zephyr continued to grow, you saw how Zephyr restructured their Pulumi projects and stacks, and incorporated the use of Stack References. This post is a complement to the post on structuring Pulumi projects, concentrating on the use of role-based access control (RBAC) and security in Zephyr&amp;rsquo;s multi-project configuration.&lt;/p&gt;
&lt;p&gt;The ultimate goal of this series is to discuss best practices for using Pulumi to manage a fairly complex containerized application. You&amp;rsquo;ve seen these practices emerge over the course of the series&amp;mdash;not all immediately, and not all right away. Structuring the blog series in this way is a deliberate decision; many best practices are &amp;ldquo;point in time&amp;rdquo; recommendations: they are context-dependent and the recommendations for any given company, like Zephyr, may change as the company and its needs change.&lt;/p&gt;
&lt;h2 id="evolving-project-structure-to-enhance-security-and-scalability"&gt;Evolving Project Structure to Enhance Security and Scalability&lt;/h2&gt;
&lt;p&gt;So far, you&amp;rsquo;ve read about how Zephyr started out with a single project and a single Git repository. Adding short-lived per-developer stacks, as described in the post on &lt;a href="https://www.pulumi.com/blog/iac-best-practices-enabling-developer-stacks-git-branches/"&gt;best practices for developer stacks and Git branches&lt;/a&gt;, didn&amp;rsquo;t really impact this structure. However, as the company grew, Zephyr&amp;rsquo;s project and Git repository structure evolved into its current form:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;ldquo;zephyr-infra&amp;rdquo; project handles base infrastructure (VPC and related constructs).&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;zephyr-k8s&amp;rdquo; project automates the Kubernetes platform layer, building atop the base infrastructure components supplied by the &amp;ldquo;zephyr-infra&amp;rdquo; project.&lt;/li&gt;
&lt;li&gt;Finally, the &amp;ldquo;zephyr-app&amp;rdquo; project handles the deployment of the online retail store application onto Kubernetes, layering on top of the platform provided by the &amp;ldquo;zephyr-k8s&amp;rdquo; project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can review the reasons for this structure in the post on &lt;a href="https://www.pulumi.com/blog/iac-best-practices-structuring-pulumi-projects/"&gt;best practices for structuring Pulumi projects&lt;/a&gt;. One of the reasons listed in the third Zephyr blog post was security:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;hellip;security is a factor that affects how projects and stacks should be structured. In Zephyr&amp;rsquo;s case, the ability for one team to affect another team&amp;rsquo;s resources was present when everything was a single project. With multiple projects, Zephyr can use stack permissions and role-based access control (RBAC) in &lt;a href="https://www.pulumi.com/product/pulumi-cloud/"&gt;Pulumi Cloud&lt;/a&gt; to appropriately control &lt;em&gt;who&lt;/em&gt; can affect &lt;em&gt;what&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The last part of that quote&amp;mdash;the part about being able to &amp;ldquo;appropriately control &lt;em&gt;who&lt;/em&gt; can affect &lt;em&gt;what&lt;/em&gt;&amp;rdquo;&amp;mdash;is another way of describing what&amp;rsquo;s known as &lt;a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege"&gt;the principle of least privilege&lt;/a&gt;. If you&amp;rsquo;re unfamiliar with this term, we recommend following the link and getting more information, because the principle of least privilege stands at the core of all the recommended practices you&amp;rsquo;ll read in this post.&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Pulumi supports a number of self-managed backends, including Amazon S3 (and S3-compatible servers like Minio or Ceph), Azure Blob Storage, and Google Cloud Storage. The RBAC functionality described in this post applies only to the managed Pulumi Cloud backend.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="understanding-the-rbac-building-blocks-in-pulumi-cloud"&gt;Understanding the RBAC Building Blocks in Pulumi Cloud&lt;/h2&gt;
&lt;p&gt;To understand how to secure your Pulumi projects and stacks in Pulumi Cloud, it is important to first explain the basic building blocks you&amp;rsquo;ll use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Organization:&lt;/em&gt; An organization represents a customer/company within Pulumi Cloud. Generally speaking, a single company like Zephyr is represented by a single organization.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Member:&lt;/em&gt; Each member represents a user account that is part of an organization. In Zephyr&amp;rsquo;s case, each Zephyr employee that needs to interact with Pulumi is a member of Zephyr&amp;rsquo;s organization in Pulumi Cloud.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Team:&lt;/em&gt; A team is a grouping of members, and is the primary component involved in assigning per-stack permissions in the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/access-management/teams/"&gt;Pulumi Cloud RBAC model&lt;/a&gt;. How you structure teams within your organization will depend on a great many different factors we&amp;rsquo;ll explore in this post.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Stack:&lt;/em&gt; A stack is a separate instance of the resources created by a Pulumi program within a project. Each stack has its own independent state and its own configuration values. With respect to RBAC, each stack is a separate entity to which one or more teams can be granted permission. In Zephyr&amp;rsquo;s case, there is a long-lived production stack for each of the separate projects, and a persistent (or long-lived) test stack for each of the separate projects. There are also the per-developer stacks, which are typically short-lived.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This diagram, also used in the post on &lt;a href="https://www.pulumi.com/blog/iac-best-practices-applying-stack-references/"&gt;best practices for stack references&lt;/a&gt;, shows the stacks and projects for Zephyr&amp;rsquo;s online store:&lt;/p&gt;
&lt;p&gt;&lt;img src="gh-repos-pulumi-projects-stacks.jpg" alt="A diagram depicting how Zephyr&amp;rsquo;s projects and stacks are structured"&gt;&lt;/p&gt;
&lt;p&gt;Now, how are these different components assembled together? At its most basic level, you would use teams to group members together, and then assign stack permissions to the team. This diagram helps illustrate the idea:&lt;/p&gt;
&lt;p&gt;&lt;img src="security-stacks-teams.jpg" alt="A diagram illustrating the relationship between stacks, teams, and members"&gt;&lt;/p&gt;
&lt;p&gt;A couple of important points emerge from the above diagram:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The relationship between stacks and teams is &lt;em&gt;many-to-many&lt;/em&gt;. That is, any given stack can have many teams assigned permissions, and any given team may be assigned permissions to many stacks.&lt;/li&gt;
&lt;li&gt;Similarly, the relationship between teams and members is also &lt;em&gt;many-to-many&lt;/em&gt; (any given team can&amp;mdash;and almost always will&amp;mdash;have multiple members, and any given member can be part of multiple teams at the same time).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="assembling-security-for-stacks"&gt;Assembling Security for Stacks&lt;/h2&gt;
&lt;p&gt;The first, and perhaps the most important, best practice with regards to securing your stacks is &lt;strong&gt;to actually use Pulumi Cloud&amp;rsquo;s RBAC functionality&lt;/strong&gt;. While this may seem obvious, there are practical implications to this statement that are useful to explore.&lt;/p&gt;
&lt;p&gt;Pulumi Cloud has the ability to set a &lt;em&gt;default stack permission&lt;/em&gt; for all members of an organization. In the screenshot below, you can see that the default permission has been set to Write:&lt;/p&gt;
&lt;p&gt;&lt;img src="pulumi-cloud-stack-permissions.jpg" alt="Screenshot showing the default stack permissions for all members"&gt;&lt;/p&gt;
&lt;p&gt;In this configuration, you are effectively disabling Pulumi Cloud&amp;rsquo;s RBAC functionality. Permissions in Pulumi Cloud are &lt;em&gt;additive&lt;/em&gt;; that is, permissions only state what you can do, not what you can&amp;rsquo;t do. Therefore, if the default stack permission is set to Write, then assigning a team read-only permissions to a stack has no effect&amp;mdash;because members of that team can read from the stack (by virtue of their inclusion in a team) &lt;em&gt;and&lt;/em&gt; can write to the stack (by virtue of the default stack permission). The team members&amp;rsquo; read-only permission is &lt;em&gt;added&lt;/em&gt; to the default stack permission for their effective permission.&lt;/p&gt;
&lt;p&gt;For this reason, Pulumi recommends &lt;strong&gt;setting the default stack permission to Read or None.&lt;/strong&gt; Setting it to Read means that all members of the organization can see and read from stacks that aren&amp;rsquo;t their own, but can&amp;rsquo;t change or modify the others stacks. Setting it to None means that members have permissions to their own stacks by default&amp;mdash;gaining any form of access to stacks other than their own requires being added to a team that has permissions to those stacks.&lt;/p&gt;
&lt;p&gt;When it comes to assigning a team access to a stack, there are three options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stack reader (read-only access; also called &amp;ldquo;Stack reader access&amp;rdquo; in some areas of the Pulumi Cloud UI)&lt;/li&gt;
&lt;li&gt;Stack editor (read/write access, but can&amp;rsquo;t delete the stack; also called &amp;ldquo;Stack write access&amp;rdquo; in the Pulumi Cloud UI)&lt;/li&gt;
&lt;li&gt;Stack admin (full access; you may also see it called &amp;ldquo;Stack admin access&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;When the &amp;ldquo;Allow organization members to create stacks and transfer stacks to this organization&amp;rdquo; is checked, like in the screenshot above, then the user (organization member) that creates a stack automatically becomes the stack admin for that stack. The user&amp;rsquo;s ability to delete the stack, however, is affected by the &amp;ldquo;Allow stack admins to delete stacks&amp;rdquo; setting.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Full details on what each of these permissions grants is detailed in &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/projects-and-stacks/"&gt;the projects and stacks documentation&lt;/a&gt; (see the &amp;ldquo;Stack Permissions&amp;rdquo; section). In accordance with the principle of least privilege, Pulumi recommends you &lt;strong&gt;grant the minimum level of access necessary&lt;/strong&gt; in order for a user (organization member) to meet their job responsibilities. You accomplish this by adding the member to a team, and then granting the team the minimum level of necessary access. &lt;em&gt;You can&amp;rsquo;t assign stack permissions directly to users.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because team membership is central to the use of stack permissions, Pulumi has several ways to make it easier to manage the relationship between teams and stacks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You can use the Pulumi Cloud user interface to assign a team access to a stack.&lt;/li&gt;
&lt;li&gt;You can use Pulumi Cloud&amp;rsquo;s REST API to control team access to stacks.&lt;/li&gt;
&lt;li&gt;You can use the Pulumi Cloud provider for Pulumi to programmatically manage team access to a stack using Pulumi itself.&lt;/li&gt;
&lt;li&gt;You can use the &lt;code&gt;--teams&lt;/code&gt; flag to &lt;code&gt;pulumi stack init&lt;/code&gt; to assign stack editor access to one or more teams when you create the stack.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In general, Pulumi recommends &lt;strong&gt;declaratively managing your Pulumi Cloud RBAC configuration&lt;/strong&gt; with the Pulumi Cloud provider (formerly known as the Pulumi Service provider), unless you have specific requirements that would prevent it. However, be aware that the Pulumi Cloud provider doesn&amp;rsquo;t allow you to change a member&amp;rsquo;s role in an organization (every member is either a &amp;ldquo;member&amp;rdquo; or an &amp;ldquo;admin&amp;rdquo; within an organization); that would have to be done via the Pulumi Cloud user interface or REST API.&lt;/p&gt;
&lt;p&gt;Pulumi also recommends &lt;strong&gt;using the &lt;code&gt;--teams&lt;/code&gt; flag with &lt;code&gt;pulumi stack init&lt;/code&gt; to ensure that new stacks are properly assigned team permissions upon creation.&lt;/strong&gt; You can then go back and fine-tune those team permissions&amp;mdash;which are set to &amp;ldquo;Stack editor&amp;rdquo; or &amp;ldquo;Stack write access&amp;rdquo; when you use the &lt;code&gt;--teams&lt;/code&gt; flag&amp;mdash;using a Pulumi program with the Pulumi Cloud provider. Alternately, teams can use a team access token when creating a new stack, and that will also grant the team permission to the newly-created stack.&lt;/p&gt;
&lt;p&gt;Finally, Pulumi recommends &lt;strong&gt;allowing users to create their own stacks.&lt;/strong&gt; Otherwise, only an organization admin would be allowed to create new stacks, and this is likely to cause a bottleneck in provisioning cloud infrastructure&amp;mdash;one of the very issues that infrastructure as code tools like Pulumi are attempting to solve! (It may be necessary in some cases to restrict this functionality, such as in certain highly regulated industries or verticals.) Preventing users from creating their own stacks would also prevent the use of per-developer stacks like Zephyr uses, which as you&amp;rsquo;ve seen can be enormously helpful in accelerating development and deployment velocity.&lt;/p&gt;
&lt;h2 id="inspecting-rbac-implementation"&gt;Inspecting RBAC Implementation&lt;/h2&gt;
&lt;p&gt;Zephyr&amp;rsquo;s RBAC implementation in Pulumi Cloud is represented in part by a diagram that you also saw earlier in this post:&lt;/p&gt;
&lt;p&gt;&lt;img src="security-stacks-teams.jpg" alt="A diagram illustrating how Zephyr set up role-based access control to their Pulumi stacks"&gt;&lt;/p&gt;
&lt;p&gt;Zephyr set the organization default stack permission to Read. This enabled teams to read all stacks, and enabled the continued use of stack references without any additional configuration. Teams were created to grant &amp;ldquo;Stack editor&amp;rdquo; (also called &amp;ldquo;Stack write access&amp;rdquo;) to stacks based on the overall organizational structure of the company. Thus, the Platform team gained access to the non-production &lt;code&gt;zephyr-infra&lt;/code&gt; and &lt;code&gt;zephyr-k8s&lt;/code&gt; stacks, while the Application team was given access to the non-production &lt;code&gt;zephyr-app&lt;/code&gt; stacks. However, only members of the Production team were given access to the production stacks in all three projects, ensuring that access to update those stacks&amp;mdash;and thus the actual resources running Zephyr&amp;rsquo;s online store&amp;mdash;remained relatively controlled.&lt;/p&gt;
&lt;h2 id="summarizing-best-practices-rbac--security"&gt;Summarizing Best Practices: RBAC &amp;amp; Security&lt;/h2&gt;
&lt;p&gt;The post covered the following guidelines for securing your stacks in Pulumi Cloud:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use Pulumi Cloud&amp;rsquo;s RBAC functionality by setting your organization&amp;rsquo;s default stack permissions to Read or None.&lt;/strong&gt; This is generally the safest way to implement the principle of least privilege, unless you have a good use case for allowing all organization members full write access to all stacks.&lt;/li&gt;
&lt;li&gt;When assigning team permissions, &lt;strong&gt;grant the minimum level of access necessary.&lt;/strong&gt; If a user isn&amp;rsquo;t responsible for making updates to a stack, then give that user stack reader permission through a team membership (remember that you can&amp;rsquo;t assign stack permissions directly to organization members, you have to use a team). Keep in mind, though: if the organization level stack permission has been set to Read, then members already have the equivalent of stack reader permissions on all stacks, so creating a team to grant stack reader permission is unnecessary and superfluous.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Declaratively manage your Pulumi Cloud RBAC configuration&lt;/strong&gt; where possible using the Pulumi Cloud provider from within a Pulumi program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the &lt;code&gt;--teams&lt;/code&gt; flag with &lt;code&gt;pulumi stack init&lt;/code&gt; to ensure that teams have stack permissions upon stack creation.&lt;/strong&gt; You can also use a team access token to accomplish the same result.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Allow users to create their own stacks.&lt;/strong&gt; Generally, turning this functionality off (found in the Settings &amp;gt; Access Management screen of Pulumi Cloud) will end up creating a bottleneck, as only organization admins would be allowed to create new stacks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next IaC Best Practices post, the focus is on &lt;a href="https://www.pulumi.com/automation/"&gt;Automation API&lt;/a&gt;. Stay tuned to see how Zephyr uses Automation API to further streamline and automate the deployment of their cloud resources!&lt;/p&gt;</description><author>Scott Lowe</author><category>best-practices</category><category>rbac</category><category>security</category></item><item><title>Access Control for Pods on Amazon EKS</title><link>https://www.pulumi.com/blog/eks-oidc/</link><pubDate>Tue, 02 Jun 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/eks-oidc/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/eks-oidc/index.png" /&gt;
&lt;p&gt;Amazon &lt;a href="https://aws.amazon.com/eks/"&gt;EKS&lt;/a&gt; clusters can use &lt;a href="https://aws.amazon.com/iam/"&gt;IAM&lt;/a&gt; roles and policies for Pods
to assign fine-grained access control of AWS services. The AWS IAM entities map into Kubernetes
&lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/"&gt;RBAC&lt;/a&gt; to configure the permissions of Pods that work with AWS
services.&lt;/p&gt;
&lt;p&gt;Together, AWS IAM and Kubernetes RBAC enable least-privileged access for your
apps, scoped to the appropriate policies and user requirements.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;In &amp;lt;100 lines of code we&amp;rsquo;ll demonstrate how EKS Pods can use AWS IAM to create
fine-grained permissions for apps that integrate with other AWS services.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#pod-access-control"&gt;Pod Access Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#create-an-oidc-provider"&gt;Create an OIDC provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#create-iam-for-a-s3-app"&gt;Create IAM for a S3 app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#deploy-a-s3-app"&gt;Deploy a S3 app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#wrap-up"&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#next-steps"&gt;Next Steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pod-access-control"&gt;Pod Access Control&lt;/h2&gt;
&lt;p&gt;AWS EKS supports using IAM entities in a Pod &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/"&gt;Service Account&lt;/a&gt; by
leveraging an &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html"&gt;OIDC provider&lt;/a&gt; connected to the Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;Continuing with the example from the &lt;a href="https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/"&gt;AWS blog post&lt;/a&gt;, when an &lt;a href="https://github.com/mhausenblas/s3-echoer"&gt;S3 app written in Go&lt;/a&gt; pushes
an object to a bucket with the AWS SDK, it will need write access to S3.&lt;/p&gt;
&lt;p&gt;When a Pod is launched with a particular Service Account, the OIDC provider works
with Kubernetes to verify the Pod&amp;rsquo;s identity, and in turn collaborates with the
&lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html"&gt;AWS Secure Token Service (STS)&lt;/a&gt; to grant the Pod temporary
credentials to use with the IAM role.&lt;/p&gt;
&lt;h2 id="create-an-oidc-provider"&gt;Create an OIDC provider&lt;/h2&gt;
&lt;p&gt;Creating an OIDC provider is as simple as toggling the &lt;code&gt;createOidcProvider&lt;/code&gt; option
in the definition of your EKS cluster.&lt;/p&gt;
&lt;p&gt;When enabled, the OIDC provider will be created and associated with the
cluster&amp;rsquo;s OIDC provider URL.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;eks&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/eks&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create an EKS cluster with default settings.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create and attach an OIDC provider to the cluster.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;eks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cluster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;myCluster&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;createOidcProvider&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="create-iam-for-a-s3-app"&gt;Create IAM for a S3 app&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll use the OIDC provider URL and Amazon Resource Name (ARN) to compose the
&lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html"&gt;AssumeRoleWithWebIdentity&lt;/a&gt;, and S3 IAM policies that will
be attached to a new S3 IAM role.&lt;/p&gt;
&lt;p&gt;After the role is configured, a Service Account for the S3 Pod will be
created, and annotated with the ARN of the S3 role to bind the two together.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/aws&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/kubernetes&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/pulumi&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create a pulumi Kubernetes provider using the cluster&amp;#39;s kubeconfig.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;k8sProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;k8s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;kubeconfig&lt;/span&gt;: &lt;span class="kt"&gt;cluster.kubeconfig.apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create a k8s namespace in the cluster.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Namespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;apps&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;k8sProvider&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Get the OIDC provider&amp;#39;s URL for the cluster.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clusterOidcProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oidcProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create the new IAM policy for the Service Account using the AssumeRoleWebWebIdentity action.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;s3&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saAssumeRolePolicy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;clusterOidcProviderUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clusterOidcProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;appsNamespaceName&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPolicyDocument&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;statements&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sts:AssumeRoleWithWebIdentity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;StringEquals&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sb"&gt;`system:serviceaccount:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:sub`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Allow&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nx"&gt;identifiers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Federated&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create a new IAM role that assumes the AssumeRoleWebWebIdentity policy.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;assumeRolePolicy&lt;/span&gt;: &lt;span class="kt"&gt;saAssumeRolePolicy.json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Attach the IAM role to an AWS S3 access policy.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saS3Rpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RolePolicyAttachment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policyArn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;arn:aws:iam::aws:policy/AmazonS3FullAccess&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;role&lt;/span&gt;: &lt;span class="kt"&gt;saRole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create a Service Account with the IAM role annotated to use with the Pod.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ServiceAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;annotations&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;eks.amazonaws.com/role-arn&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;saRole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;k8sProvider&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="deploy-a-s3-app"&gt;Deploy a S3 app&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll deploy the &lt;a href="https://github.com/pulumi/pulumi-eks/tree/master/examples/oidc-iam-sa"&gt;S3 app&lt;/a&gt; to use the new IAM-backed Service Account.&lt;/p&gt;
&lt;p&gt;Once the Pod is running, the Service Account annotation will be automatically
managed by a &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers"&gt;Kubernetes dynamic admission controller&lt;/a&gt; run
by EKS on your behalf.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/aws/amazon-eks-pod-identity-webhook/"&gt;AWS EKS webhook&lt;/a&gt; manages Pod identity, and injects STS
credentials into the Pod to use with the S3 role.&lt;/p&gt;
&lt;p&gt;With the credentials, the app can successfully upload data to S3.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/kubernetes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pod-irsa-job-bucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regionName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRegion&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kr"&gt;async&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})).&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3Pod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;k8s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Pod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;podName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;labels&lt;/span&gt;: &lt;span class="kt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appsNamespaceName&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;serviceAccountName&lt;/span&gt;: &lt;span class="kt"&gt;sa.metadata.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;podName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;amazonlinux:2018.03&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interpolate&lt;/span&gt;&lt;span class="sb"&gt;`curl -sL -o /s3-echoer https://git.io/JfnGX &amp;amp;&amp;amp; chmod +x /s3-echoer &amp;amp;&amp;amp; echo This is an in-cluster test | /s3-echoer &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;bucketName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; &amp;amp;&amp;amp; sleep 3600`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AWS_DEFAULT_REGION&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;: &lt;span class="kt"&gt;regionName&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ENABLE_IRP&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;: &lt;span class="kt"&gt;provider&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="wrap-up"&gt;Wrap-Up&lt;/h2&gt;
&lt;p&gt;Leveraging AWS IAM for Pod workloads is a secure and effective means of limiting
privileged execution, and provides a native experience for users.&lt;/p&gt;
&lt;p&gt;Pod IAM can be extended further by also using the Kubernetes RBAC system. This
allows configuring permissions for Kubernetes API resources, and handle scenarios
such as limiting the namespace an IAM role can use, and what resources can be
managed in the namespace.&lt;/p&gt;
&lt;h2 id="next-steps"&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Learn more about how &lt;a href="https://www.pulumi.com/registry/packages/kubernetes/"&gt;Pulumi works with Kubernetes&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/iac/get-started/kubernetes/"&gt;get started&lt;/a&gt;
if you&amp;rsquo;re new.&lt;/p&gt;
&lt;p&gt;Check out code examples for the S3 app referenced in this post,
along with other access control scenarios for EKS.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumi/pulumi-eks/tree/master/examples/oidc-iam-sa"&gt;S3 app: EKS and an OIDC provider for Pod IAM.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumi/pulumi-eks/tree/master/examples/scoped-kubeconfigs"&gt;Create an EKS cluster with Kubernetes RBAC for a Developer scoped IAM role.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumi/pulumi-eks/tree/master/examples"&gt;More EKS examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Watch the video below for more details on how OIDC and Kubernetes RBAC works in
EKS. We demonstrate how to deploy &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs.html"&gt;fluentd-cloudwatch&lt;/a&gt; with
IAM to forward Pod logs to &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html"&gt;AWS CloudWatch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also follow us on &lt;a href="https://twitter.com/pulumicorp"&gt;Twitter&lt;/a&gt;,
subscribe to &lt;a href="https://www.youtube.com/channel/UC2Dhyn4Ev52YSbcpfnfP0Mw"&gt;PulumiTV&lt;/a&gt; on YouTube,
or join our &lt;a href="https://slack.pulumi.com/"&gt;Community Slack&lt;/a&gt; channel if you have any questions.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/7qN9ABgmK9M?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;</description><author>Mike Metral</author><category>aws</category><category>kubernetes</category><category>eks</category><category>rbac</category></item></channel></rss>