Hi all, wanted to flag a small docs vs. behavior m...
# getting-started
f
Hi all, wanted to flag a small docs vs. behavior mismatch I hit while testing ESC credential rotators. The rotators docs state:
To 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.
👀 2
✅ 1
f
Hi, I'm not able to reproduce this. if
managingUser
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 helpful
f
Hi @freezing-pilot-97749, thanks for looking into this. I've explained my flow in the diagram below. Also, here's the env definition of both envs: ManagingCreds env:
Copy code
values:
  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:
Copy code
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.
f
I think the issue is here
Copy code
connector:
            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
connector
f
Hey @freezing-pilot-97749, thanks for your response. Can you share with me what I should do instead to make it all work seamlessly?
f
An easy way is to separate your
aws-login
creds into a separate environment that you have
open
access to
f
Thanks @freezing-pilot-97749, that makes sense. Just want to confirm I've got the structure right. You're suggesting I split into three environments: 1.
postgresrotation/AwsLogin
(new) holds just the
aws-login
creds, and the team token needs OPEN here since the connector
login
is evaluated at open time:
Copy code
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:
Copy code
values:
  managingUser:
    username: managing_username
    password:
      fn::secret:
        ciphertext: <redacted>
3.
postgresrotation/Rotator
references each from the right place:
Copy code
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?
f
Yes that was what I was thinking. I recommended a separate
aws-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.
f
Ok perfect and yes I can confirm that this works on my end as well. Now just to clarify - my understanding of normal ESC composition is that whether I use an explicit
imports:
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?
f
Correct, that is because the managing credentials for the rotators aren't surfaced in a normal open. but this does highlight a documentation gap that we can improve on - i'll bring this up to the team
f
Perfect, thanks so much!
🎉 1