Skip to content
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

Implement External Approval + Other small features #303

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mvo-dev
Copy link

@mvo-dev mvo-dev commented Feb 28, 2024

This PR aims to implement a new activation type namely external approval. External approval works as follows:

A user/group is given an IAM binding with the has({}.externalApprovalConstraint) condition.
Another user/group is given an equivalent IAM binding with the has({}.reviewerPrivilege) condition.
Only the user(s) with the externalApprovalConstraint can request activation of the associated privilege and only the user(s) with the reviewerPrivilege can be selected as reviewers.

In addition to this major change a few additional features have been added:

Ability to control fine-grained requester/reviewer associations on the same role using "topics".
Ability to transform email addresses of users before sending emails using SMTP.

External approval

The current limitation of only providing the option of peer approval for MPA approval makes the application unsuitable for some larger organizations where the requester and reviewer privileges have to be separated to accommodate more complex approval flows.

To accommodate this need a new activation type has been implemented, namely that of external approval. External approval is a new type of MPA where the users capable of requesting activation of privileges are not able to review activation requests (unless specifically granted a reviewer privilege).

The feature introduces two new IAM conditions that work similarly to the existing has({}.externalApprovalConstraint) condition used for peer approval. The two conditions are:
has({}.externalApprovalConstraint) and has({}.reviewerPrivilege)
Only users explicitly granted a reviewer privilege can be selected as reviewers of an activation request for a privilege requiring external approval.

For backwards compatibility reasons the IAM condition for peer approval is still has({}.multiPartyApprovalConstraint) although it would make sense to change this to has({}.peerApprovalConstraint) given the new distinction.

Topics

To allow even more fine-grained control in configuring who can review which requests a new notion of topics (also referred to as teams in the documentation) has been introduced.

A topic is an arbitrary name given at the end of an MPA eligible condition. Only reviewers/peers with a binding given the same topic are able to review activation requests. For instance Alice might have a role binding for the Editor role with the has({}.externalApprovalConstraint.codeNinjas) condition, the topic here is codeNinjas. If Bob is granted the Editor role with the has({}.reviewerPrivilege.cloudExperts) condition he will be unable to review this request. If on the other hand he was granted the role with the has({}.reviewerPrivilege.codeNinjas) condition, then he would be able to review Alice's request and could be selected as a reviewer by Alice.

Reviewer privileges granted without specifying a topic allows the reviewer to review ALL activation requests for the appropriate role on the appropriate scope.

Email address transformation

Currently there is an issue with sending emails to some externals of a GCP organization. Suppose for instance that Alice in the example.com organization invites a Bob of the mydomain.org organization. In some cases such an invitation gives Bob the email address bob_mydomain.org@example.com when logged into GCP. Since this address is purely a username and does not correspond to any real email address the JIT Access application will fail to send or cc activation requests to such a user.

To fix this issue the following new configuration options have been introduced:

MAIL_INTERNALS_PATTERN

Regex pattern to be matched for capturing (and transforming) the mail addresses of internals to the organization. For example: (.*)@example.com

Used in conjunction with MAIL_INTERNALS_TRANSFORM to transform mail address for instance by replacing domain.

Required for MPA (.*) -
MAIL_INTERNALS_TRANSFORM

String formatting pattern to be used with groups captured from MAIL_INTERNALS_PATTERN to transform mail addresses of internals. For example: %s@domain.com

Used in conjunction with MAIL_INTERNALS_PATTERN to transform mail address for instance by replacing domain.

Required for MPA %s -
MAIL_EXTERNALS_PATTERN

Regex pattern to be matched for capturing (and transforming) the mail addresses of externals to the organization. For example: (.*)@external.com

Used in conjunction with MAIL_EXTERNALS_TRANSFORM to transform mail address for instance by replacing domain.

Optional -
MAIL_EXTERNALS_TRANSFORM

String formatting pattern to be used with groups captured from MAIL_EXTERNALS_PATTERN to transform mail addresses of externals. For example: %s@domain.com

Used in conjunction with MAIL_EXTERNALS_PATTERN to transform mail address for instance by replacing domain.

Optional -

* Add region setting for resource creation in integration tests

* Make the default replication mode automatic

* Refactor code to seperate out entitlement type from activation type

* Implement external review

* Refactor entitlement code and cleanup EntitlementType vs ActivationType

* Implement topics to allow for additional flexibility in confiiguration

* Update tab size

* Minor documentation update

* Cleanup code and fix regex string

* Cleanup comment

* Clean up test and fix regex + getTopic

* Allow configuration of regex captures and transforms for mail addresses

* Remove singleton

* Update config documentation

* Updated error test

* Minor update of documentation

* Update index.html to display correct status

* Update MPA documentation

* Update base readme

* Fix typo in MPA documentation changes
@mvo-dev mvo-dev changed the title Squash commits to amend author (#8) Implement External Approval + Other small features Feb 28, 2024
@mvo-dev mvo-dev marked this pull request as ready for review February 28, 2024 15:10
@jpassing
Copy link
Collaborator

Thank you for creating this PR and the additional context.

I definiteltly see a need for all 3 features and especially the "external approval" is something that has been brought up several times before. Let me take a closer look at the code and see how it aligns with other work that's currently in progress.

Regarding the email address transformation: Another approach here could be to look up the user's secondary/alternative email addresses in Cloud identity/Workspace. But I guess your external users don't have these configured, hence the rule-based approach?

@mvo-dev
Copy link
Author

mvo-dev commented Feb 29, 2024

Thank you for creating this PR and the additional context.

I definiteltly see a need for all 3 features and especially the "external approval" is something that has been brought up several times before. Let me take a closer look at the code and see how it aligns with other work that's currently in progress.

Regarding the email address transformation: Another approach here could be to look up the user's secondary/alternative email addresses in Cloud identity/Workspace. But I guess your external users don't have these configured, hence the rule-based approach?

In our case the recovery email of externals is the correct one, so using that would be a possibility. The regex analysis would still be needed to identify externals though, so I would say that adding the extra flexibility of being able to configure also the transformation comes at a low cost in terms of code complexity.

@jpassing
Copy link
Collaborator

jpassing commented Mar 7, 2024

In our case the recovery email of externals is the correct one, so using that would be a possibility. The regex analysis would still be needed to identify externals though, so I would say that adding the extra flexibility of being able to configure also the transformation comes at a low cost in terms of code complexity.

That makes sense.

I figure a different (and maybe more generic) way to solve this issue would be to configure a CEL expression for mapping email addresses. For example:

email.endsWith('_altostrat.com@example.com') 
 ? email.extract('{name}_altostrat.com@example.com') + '@altostrat.com'
 : email

would map alice_altostrat.com@example.com to alice@altostrat.com while leaving bob@example.com as-is. Wdyt?

I recently wrote something similar (incl. an implementation of extract()) for a different purpose, so I could add that.

@mvo-dev
Copy link
Author

mvo-dev commented Mar 7, 2024

In our case the recovery email of externals is the correct one, so using that would be a possibility. The regex analysis would still be needed to identify externals though, so I would say that adding the extra flexibility of being able to configure also the transformation comes at a low cost in terms of code complexity.

That makes sense.

I figure a different (and maybe more generic) way to solve this issue would be to configure a CEL expression for mapping email addresses. For example:

email.endsWith('_altostrat.com@example.com') 
 ? email.extract('{name}_altostrat.com@example.com') + '@altostrat.com'
 : email

would map alice_altostrat.com@example.com to alice@altostrat.com while leaving bob@example.com as-is. Wdyt?

I recently wrote something similar (incl. an implementation of extract()) for a different purpose, so I could add that.

Sounds good. That would probably also clean up the configuration settings a bit.

jpassing added a commit that referenced this pull request Mar 20, 2024
Apply a CEL expression to derive an email address from a user ID. This enables multi-party approval to be used in scenarios where some (or all) users in Cloud Identity/Workspace have non-routable email addresses.

The CEL expression can be configured using a new option, SMTP_ADDRESS_MAPPING. For example:

user.email.extract('{handle}@example.com') + '@test.example.com'
When SMTP_ADDRESS_MAPPING is not configured, JIT Access uses the user ID as-is, preseving the current behavior.

This PR is inspired by, and partially supersedes #303.

Co-authored-by: mvo-dev <mvo@cvation.com>
jpassing added a commit that referenced this pull request Mar 25, 2024
Apply a CEL expression to derive an email address from a user ID. This enables multi-party approval to be used in scenarios where some (or all) users in Cloud Identity/Workspace have non-routable email addresses.

The CEL expression can be configured using a new option, SMTP_ADDRESS_MAPPING. For example:

user.email.extract('{handle}@example.com') + '@test.example.com'
When SMTP_ADDRESS_MAPPING is not configured, JIT Access uses the user ID as-is, preseving the current behavior.

This PR is inspired by, and partially supersedes #303.

Co-authored-by: mvo-dev <mvo@cvation.com>
jpassing added a commit that referenced this pull request Mar 25, 2024
…340)

Apply a CEL expression to derive an email address from a user ID. This 
enables multi-party approval to be used in scenarios where some (or all) 
users in Cloud Identity/Workspace have non-routable email addresses.

The CEL expression can be configured using a new option, 
SMTP_ADDRESS_MAPPING. For example:

    user.email.extract('{handle}@example.com') + '@test.example.com'

When SMTP_ADDRESS_MAPPING is not configured, JIT Access uses
the user ID as-is, preseving the current behavior.

This PR is inspired by, and partially supersedes #303, which was authored
by mvo-dev <mvo@cvation.com>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants