-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Can grant access to emails (user, group, SA) #8357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
89a7a5b to
57f26df
Compare
src/apphosting/secrets/index.ts
Outdated
| } | ||
|
|
||
| /** | ||
| * Grants the following users or grouips access to the provided secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * Grants the following users or grouips access to the provided secret. | |
| * Grants the following users or groups access to the provided secret. |
src/apphosting/secrets/index.ts
Outdated
| existingBindings = (await gcsm.getIamPolicy({ projectId, name: secretName })).bindings || []; | ||
| } catch (err: unknown) { | ||
| throw new FirebaseError( | ||
| `Failed to get IAM bindings on secret: ${secretName}. Ensure you have the permissions to do so and try again.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we link to https://cloud.google.com/secret-manager/docs/manage-access-to-secrets#required-roles to guide the users a little more here?
I'd love to link to a Firebase doc, but seems like we don't have a doc.
| ) | ||
| .option("-l, --location <location>", "backend location", "-") | ||
| .option("-b, --backend <backend>", "backend name") | ||
| .option("-u, --emails <emails>", "comma delmited list user or group emails") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want to update the short flag too or keep it?
| .option("-u, --emails <emails>", "comma delmited list user or group emails") | |
| .option("-e, --emails <emails>", "comma delmited list user or group emails") |
| ) | ||
| .option("-l, --location <location>", "backend location", "-") | ||
| .option("-b, --backend <backend>", "backend name") | ||
| .option("-u, --emails <emails>", "comma delmited list user or group emails") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .option("-u, --emails <emails>", "comma delmited list user or group emails") | |
| .option("-u, --emails <emails>", "comma delimited list user or group emails") |
| const accounts = secrets.toMulti(secrets.serviceAccountsForBackend(projectNumber, backend)); | ||
|
|
||
| await secrets.grantSecretAccess(projectId, projectNumber, secretName, accounts); | ||
| await Promise.all( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer Promise.allSettled?
| .description("grant service accounts permissions to the provided secret") | ||
| export const command = new Command("apphosting:secrets:grantaccess <secretNames>") | ||
| .description( | ||
| "grant service accounts permissions to the provided secret(s). Can pass one or more secrets, separated by a comma", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "grant service accounts permissions to the provided secret(s). Can pass one or more secrets, separated by a comma", | |
| "grant service accounts or users permissions to the provided secret(s). Can pass one or more secrets, separated by a comma", |
| const accounts = secrets.toMulti(secrets.serviceAccountsForBackend(projectNumber, backend)); | ||
|
|
||
| await Promise.all( | ||
| await Promise.allSettled( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wanna explicitly handle errors here?
Or we could just go back to using Promise.all() instead... 🤷🏼
e.g.
const results = await Promise.allSettled(
secretList.map((secretName) =>
secrets.grantSecretAccess(projectId, projectNumber, secretName, accounts)
)
);
const failures = results.filter(result => result.status === 'rejected');
if (failures.length > 0) {
throw new Error(`Failed to grant access to ${failures.length}/${results.length} secrets`);
}
Part of the new work to encourage the use of test secrets in the emulator.
Unfortunately there is no general API to figure out whether an email address is a service account, user, or group. Fortunately, IAM will return an error with a clear message on what type of principal the secret was on error so we can brute force our way to success ¯_(ツ)_/¯