Skip to content

Group creation requests API#370

Open
eguerrant wants to merge 7 commits intomainfrom
group_creation_requests
Open

Group creation requests API#370
eguerrant wants to merge 7 commits intomainfrom
group_creation_requests

Conversation

@eguerrant
Copy link
Contributor

@eguerrant eguerrant commented Feb 13, 2026

Description

This PR introduces the concept of 'Group Creation Requests', sometimes referred to in the code as Group Requests. This will allow users to, as the name suggests, request that a group is created.

The user provides the desired group:

  • Name
  • Description
  • Tags
  • Ownership Duration
  • Group type
  • (if an App Group) Associated app
  • Request reason (this will also be used as the ownership reason for the initial owner)

This request is then created so that Access admins (and app owners if the requested group is an app group) can approve/reject it. Users may also reject their own requests.

  • If an app owner requests that a group is added to their own app, it will automatically be approved
    • There's a weird edge case here where the group or parent app has a tag that prevents owners from managing their own membership. If that constraint is applied to the group, auto approval does not add the app owner as a direct owner (but the user will still own the group since they own the app)
  • If the requested or approved ownership duration is longer than tag constraints allow, it will automatically be lowered to the maximum allowed value. In the case of app groups, app tags will also be applied.
  • The requesting user will automatically be added as the owner of the group. (This may be changed in the future to allow requesters to specify an owner)
  • The approving user may modify the group name, description, tags, app, group type, and ownership duration before approving

Additional changes have been added to the plugins and audit logging to support the new request type

Notes

A few other bug fixes and circular import fixes added in as well (eg. in modify_group_tags.py)

How to review

Unfortunately, this PR is massive and not easily broken up. Probably start with models and schemas in case any changes need to be made there (which will affect the rest of the code), then maybe test cases to see if there's any edge cases missing or the behavior is unexpected, then operations, then the rest?

TODO after initial review

  • Database migrations (I'd like to avoid having to re-do them if I have to change the model after review)

TODO in follow up PRs:

  • Notifications update
  • UI update

@eguerrant eguerrant changed the title Group creation requests Group creation requests API Feb 13, 2026
@eguerrant eguerrant marked this pull request as ready for review February 18, 2026 00:23
Copy link
Contributor

@barborico barborico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed schemas; will continue with the rest tomorrow!

description=resolved_description,
)

created_group = CreateGroup(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It would be good for us to be able to tie the "group created" audit log to the corresponding request ID.

requester = fields.Nested(lambda: OktaUserSchema)
active_requester = fields.Nested(lambda: OktaUserSchema)
resolver = fields.Nested(lambda: OktaUserSchema)
active_resolver = fields.Nested(lambda: OktaUserSchema)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this pattern is used elsewhere, but I don't really understand it. What's the purpose of having two user properties each for requester and resolver? Aren't they gonna be the same if the user isn't deleted, and one will be null otherwise?

)


class GroupRequestSchema(SQLAlchemyAutoSchema):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that appears to be missing from the group request schema but is present when creating app groups directly is plugin config (a JSON blob). Seems like that should be included here, e.g. if someone is requesting to create a group for an app with a plugin configured.

active_requester = fields.Nested(lambda: OktaUserSchema)
resolver = fields.Nested(lambda: OktaUserSchema)
active_resolver = fields.Nested(lambda: OktaUserSchema)
approved_group = fields.Nested(lambda: OktaGroup)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: created_group may be clearer

"requested_group_type",
"requested_app_id",
"requested_group_tags",
"requested_ownership_ending_at",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just leave the ownership indefinite, and then they can always modify ownership after the group is created? Seems like it may be confusing.

status = fields.Enum(AccessRequestStatus, load_only=True)
requester_user_id = fields.String(load_only=True)
requested_group_name = fields.String(load_only=True)
assignee_user_id = fields.String(load_only=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the assignee the same as the requestor? Seems like this could be omitted, or replaced with the associated app.

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