fresh-mechanic-57821
10/05/2026, 7:21 PMTo open an environment, a user must have OPEN permissions on the environment (and does not need any permissions for the implicitly imported environment which provides the rotation credentials).In my testing that doesn't hold. Opening a rotator environment fails if the caller lacks
OPEN on the implicitly imported managing-credentials environment, not just rotating it.
Setup
• `postgresrotation/Rotator`: the rotator env (Postgres connector-generated)
• `postgresrotation/ManagingCreds`: the managing-creds env, pulled in implicitly via ${environments.postgresrotation.ManagingCreds....}
• A team token with WRITE on Rotator and no permission on ManagingCreds
What I see as that team:
• pulumi env open postgresrotation/Rotator → [0] Diags: you do not have permission to open environment '<my-org>/postgresrotation/ManagingCreds'
• Even pulumi env get Rotator fails the same way.
• pulumi env rotate Rotator → [400] Bad Request: failed to check environment: Rotator:8,22-77 ... / Rotator:13,25-84 ... you do not have permission to open environment 'ManagingCreds'
The error points right at the lines in the Rotator definition that reference ManagingCreds, so it looks like those implicit references get evaluated under the caller's identity at open time, which means OPEN on ManagingCreds is effectively required, contrary to the doc note. Granting OPEN on ManagingCreds makes `open`/`rotate` work as expected.
Is the docs wording the intended behavior, or is open supposed to skip evaluating those rotation-credential references? Happy to share more detail if helpful.freezing-pilot-97749
10/05/2026, 10:43 PMmanagingUser is the only key that contains the implicit import, you should be able to open postgresrotation/Rotator without having open access to postgresrotation/ManagingCreds. Are you importing it elsewhere in the environment? If you can share a minimal environment definition to reproduce this, that would be helpfulfresh-mechanic-57821
10/06/2026, 1:21 AMvalues:
managingUser:
username: managing_username # Replace with your user value
password:
fn::secret:
ciphertext: <redacted>
awsLogin:
fn::open::aws-login:
oidc:
duration: 1h
roleArn: <redacted-iam-role-that-can-permissions-to-invoke-rotator-lambda>
sessionName: pulumi-esc-secret-rotator
Rotator env:
values:
dbRotator:
fn::rotate::postgres:
inputs:
database:
connector:
awsLambda:
login: ${environments.postgresrotation.ManagingCreds.awsLogin}
lambdaArn: <redacted>
database: <redacted>
host: <redacted>
port: 5432
managingUser: ${environments.postgresrotation.ManagingCreds.managingUser}
rotateUsers:
username1: user1
username2: user2
state:
current:
password:
fn::secret:
ciphertext: <redacted>
username: user1
previous:
password:
fn::secret:
ciphertext: <redacted>
username: user2
We are invoking the pulumi env rotate xanadu/postgresrotation/Rotator env to manually trigger the rotation. Let me know if there's anything different I should do.freezing-pilot-97749
10/06/2026, 1:36 PMconnector:
awsLambda:
login: ${environments.postgresrotation.ManagingCreds.awsLogin}
For the postgres rotator, managingUser is set as the "rotate only" key, meaning that you don't need access to it in order to open. but you still need open access to connectorfresh-mechanic-57821
10/06/2026, 1:41 PMfreezing-pilot-97749
10/06/2026, 2:00 PMaws-login creds into a separate environment that you have open access tofresh-mechanic-57821
10/06/2026, 2:07 PMpostgresrotation/AwsLogin (new) holds just the aws-login creds, and the team token needs OPEN here since the connector login is evaluated at open time:
values:
awsLogin:
fn::open::aws-login:
oidc:
duration: 1h
roleArn: <redacted>
sessionName: pulumi-esc-secret-rotator
2. postgresrotation/ManagingCreds now holds only managingUser, which stays rotate only so the token needs no permission here:
values:
managingUser:
username: managing_username
password:
fn::secret:
ciphertext: <redacted>
3. postgresrotation/Rotator references each from the right place:
login: ${environments.postgresrotation.AwsLogin.awsLogin} # open time, needs OPEN
managingUser: ${environments.postgresrotation.ManagingCreds.managingUser} # rotate only, no OPEN needed
Is that the intended structure?
A couple of follow ups:
What happens if I instead put the aws-login block directly inside the Rotator env (inline under connector.awsLambda.login), rather than in a separate third environment? Does that work, and are there any downsides?
My concern is that the three env pattern means every secret I want to rotate ends up needing roughly three separate environments to manage, which feels like a lot of overhead to maintain at scale. Is that actually the recommended best practice, or is there a cleaner pattern you'd suggest for managing many rotators?freezing-pilot-97749
10/06/2026, 2:25 PMaws-login environment because I assumed it may be reused for your other environments, but if it's not, putting the block directly inside the Rotator env is even easier.fresh-mechanic-57821
10/06/2026, 3:29 PMimports: or an implicit ${environments.<base>...} reference, opening the composed env requires OPEN on both the composed env and the base env, since those values get resolved at open time under the caller's identity.
But in the case of database creds rotators, that's the only exception when you try to OPEN the composed env containing the rotated creds without having access to the implicitly referenced ManagingCreds env. Correct?freezing-pilot-97749
10/06/2026, 3:54 PMfresh-mechanic-57821
10/06/2026, 3:55 PM