Skip to content
Snippets Groups Projects
Commit ed47ba01 authored by Smriti Garg's avatar Smriti Garg :speech_balloon:
Browse files

Merge branch 'smriti-421420/service_access_tokens_optional_expiration_ui' into 'master'

API and UI changes for group and application setting

See merge request gitlab-org/gitlab!135971



Merged-by: default avatarSmriti Garg <sgarg@gitlab.com>
Approved-by: default avatarDrew Blessing <drew@gitlab.com>
Approved-by: Lorenz van Herwaarden's avatarLorenz van Herwaarden <lvanherwaarden@gitlab.com>
Approved-by: default avatarJon Glassman <jglassman@gitlab.com>
Reviewed-by: default avatarDrew Blessing <drew@gitlab.com>
Reviewed-by: Lorenz van Herwaarden's avatarLorenz van Herwaarden <lvanherwaarden@gitlab.com>
Co-authored-by: default avatarJon Glassman <jglassman@gitlab.com>
parents b43a8105 c8d72772
No related branches found
No related tags found
1 merge request!135971API and UI changes for group and application setting
Pipeline #1068093608 passed
Showing
with 109 additions and 1 deletion
......@@ -30,6 +30,7 @@
= render_if_exists 'admin/application_settings/git_two_factor_session_expiry', form: f
= render_if_exists 'admin/application_settings/personal_access_token_expiration_policy', form: f
= render_if_exists 'admin/application_settings/service_access_tokens_expiration_enforced', form: f
= render_if_exists 'admin/application_settings/ssh_key_expiration_policy', form: f
.form-group
......
......@@ -43,6 +43,7 @@
= render 'groups/settings/project_creation_level', f: f, group: @group
= render 'groups/settings/subgroup_creation_level', f: f, group: @group
= render_if_exists 'groups/settings/prevent_forking', f: f, group: @group
= render_if_exists 'groups/settings/service_access_tokens_expiration_enforced', f: f, group: @group
= render 'groups/settings/two_factor_auth', f: f, group: @group
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
= render 'groups/settings/membership', f: f, group: @group
......
......@@ -1340,6 +1340,10 @@ Example response:
}
```
| Attribute | Type | Required | Description |
| --------- | --------------- | -------- | ----------- |
| `expires_at` | date | no | Personal access token expiry date. When left blank, the token follows the [standard rule of expiry for personal access tokens](../user/profile/personal_access_tokens.md#when-personal-access-tokens-expire). |
### Rotate a Personal Access Token for Service Account User
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/406781) in GitLab 16.1.
......@@ -1484,6 +1488,7 @@ PUT /groups/:id/hooks/:hook_id
| `releases_events` | boolean | no | Trigger hook on release events. |
| `subgroup_events` | boolean | no | Trigger hook on subgroup events. |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook. |
| `service_access_tokens_expiration_enforced` | boolean | no | Require service account access tokens to have an expiration date. |
| `token` | string | no | Secret token to validate received payloads. Not returned in the response. When you change the webhook URL, the secret token is reset and not retained. |
### Delete group hook
......
......@@ -542,6 +542,7 @@ listed in the descriptions of the relevant settings.
| `rsa_key_restriction` | integer | no | The minimum allowed bit length of an uploaded RSA key. Default is `0` (no restriction). `-1` disables RSA keys. |
| `session_expire_delay` | integer | no | Session duration in minutes. GitLab restart is required to apply changes. |
| `security_policy_global_group_approvers_enabled` | boolean | no | Whether to look up scan result policy approval groups globally or within project hierarchies. |
| `service_access_tokens_expiration_enforced` | boolean | no | Flag to indicate if token expiry date can be optional for service account users |
| `shared_runners_enabled` | boolean | no | (**If enabled, requires:** `shared_runners_text` and `shared_runners_minutes`) Enable shared runners for new projects. |
| `shared_runners_minutes` **(PREMIUM ALL)** | integer | required by: `shared_runners_enabled` | Set the maximum number of compute minutes that a group can use on shared runners per month. |
| `shared_runners_text` | string | required by: `shared_runners_enabled` | Shared runners text. |
......
......@@ -137,6 +137,42 @@ Personal access tokens expire on the date you define, at midnight, 00:00 AM UTC.
- In GitLab Ultimate, administrators can
[limit the allowable lifetime of access tokens](../../administration/settings/account_and_limit_settings.md#limit-the-lifetime-of-access-tokens). If not set, the maximum allowable lifetime of a personal access token is 365 days.
- In GitLab Free and Premium, the maximum allowable lifetime of a personal access token is 365 days.
- If you do not set an expiry date when creating a personal access token, the expiry date is set to the
[maximum allowed lifetime for the token](../../administration/settings/account_and_limit_settings.md#limit-the-lifetime-of-access-tokens).
If the maximum allowed lifetime is not set, the default expiry date is 365 days from the date of creation.
### Service Accounts
You can [create a personal access token for a service account](../../api/groups.md#create-personal-access-token-for-service-account-user) with no expiry date.
NOTE:
Allowing personal access tokens for service accounts to be created with no expiry date only affects tokens created after you change this setting. It does not affect existing tokens.
#### GitLab.com
Prerequisite:
- You must have the Owner role in the top-level group.
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > Permissions and group features**.
1. Clear the **Service account token expiration** checkbox.
You can now create personal access tokens for a service account user with no expiry date.
#### Self-managed GitLab
Prerequisite:
- You must be an administrator for your self-managed instance.
1. On the left sidebar, select **Search or go to**.
1. Select **Admin Area**.
1. Select **Settings > General**.
1. Expand **Account and limit**.
1. Clear the **Service account token expiration** checkbox.
You can now create personal access tokens for a service account user with no expiry date.
## Create a personal access token programmatically **(FREE SELF)**
......
......@@ -53,6 +53,8 @@ Prerequisite:
You define the scopes for the service account by [setting the scopes for the personal access token](personal_access_tokens.md#personal-access-token-scopes).
Optional. You can [create a personal access token with no expiry date](personal_access_tokens.md#when-personal-access-tokens-expire).
The response includes the personal access token value.
1. Make this service account a group or project member by [manually adding the service account user to the group or project](#add-a-service-account-to-subgroup-or-project).
......@@ -74,6 +76,8 @@ Prerequisite:
You define the scopes for the service account by [setting the scopes for the personal access token](personal_access_tokens.md#personal-access-token-scopes).
Optional. You can [create a personal access token with no expiry date](personal_access_tokens.md#when-personal-access-tokens-expire).
The response includes the personal access token value.
1. Make this service account a group or project member by
......
......@@ -120,7 +120,8 @@ def visible_application_setting_attributes
:maven_package_requests_forwarding,
:lock_maven_package_requests_forwarding],
default_branch_protection_restriction_in_groups: :group_owners_can_manage_default_branch_protection,
group_ip_restriction: :globally_allowed_ips
group_ip_restriction: :globally_allowed_ips,
service_accounts: :service_access_tokens_expiration_enforced
}.each do |license_feature, attribute_names|
if License.feature_available?(license_feature)
attrs += Array.wrap(attribute_names)
......
......@@ -5,6 +5,7 @@ module GroupsController
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
include PreventForkingHelper
include ServiceAccessTokenExpirationHelper
include GroupInviteMembers
include ::Admin::IpRestrictionHelper
......@@ -96,6 +97,7 @@ def group_params_ee
params_ee << :max_pages_size if can?(current_user, :update_max_pages_size)
params_ee << :max_personal_access_token_lifetime if current_group&.personal_access_token_expiration_policy_available?
params_ee << :prevent_forking_outside_group if can_change_prevent_forking?(current_user, current_group)
params_ee << :service_access_tokens_expiration_enforced if can_change_service_access_tokens_expiration?(current_user, current_group)
params_ee << :code_suggestions if ai_assist_ui_enabled?
params_ee << { value_stream_dashboard_aggregation_attributes: [:enabled] } if can?(current_user, :modify_value_stream_dashboard_settings, current_group)
params_ee << :product_analytics_enabled
......
......@@ -128,6 +128,7 @@ def self.possible_licensed_attributes
maintenance_mode
maintenance_mode_message
globally_allowed_ips
service_access_tokens_expiration_enforced
]
end
......
# frozen_string_literal: true
module ServiceAccessTokenExpirationHelper
def can_change_service_access_tokens_expiration?(current_user, group)
group&.root? && can?(current_user, :admin_service_accounts, group)
end
end
......@@ -626,6 +626,10 @@ def prevent_forking_outside_group?
root_ancestor.saml_provider&.prohibited_outer_forks?
end
def service_access_tokens_expiration_enforced?
namespace_settings.service_access_tokens_expiration_enforced if namespace_settings
end
def minimal_access_role_allowed?
feature_available?(:minimal_access_role) && !has_parent?
end
......
......@@ -155,6 +155,8 @@ def product_analytics_allowed
allow_merge_on_skipped_pipeline
only_allow_merge_if_all_discussions_are_resolved
experiment_features_enabled
third_party_ai_features_enabled
service_access_tokens_expiration_enforced
].freeze
override :allowed_namespace_settings_params
......
......@@ -19,6 +19,13 @@ def execute
s_('GroupSettings|Prevent forking setting was not saved')
)
end
unless can_update_service_access_tokens_expiration_enforced?
group.errors.add(
:service_access_tokens_expiration_enforced,
s_('GroupSettings|Service access tokens expiration enforced setting was not saved')
)
end
end
private
......@@ -35,6 +42,15 @@ def can_update_prevent_forking?
end
end
def can_update_service_access_tokens_expiration_enforced?
return true unless settings_params.key?(:service_access_tokens_expiration_enforced)
return true if group.root? && can?(current_user, :admin_service_accounts, group)
settings_params.delete(:service_access_tokens_expiration_enforced)
false
end
def ai_settings_changed?
::NamespaceSettings::AiRelatedSettingsChangedEvent::AI_RELATED_SETTINGS.any? do |setting|
group.namespace_settings.changes.key?(setting)
......
- return if ::Gitlab::Saas.enabled?
- return unless License.feature_available?(:service_accounts)
- form = local_assigns.fetch(:form)
.form-group
= form.label :service_access_tokens_expiration_enforced, _('Service account token expiration'), class: 'label-bold'
- pat_expiry_rules_link = link_to('', help_page_path('user/profile/personal_access_tokens', anchor: 'when-personal-access-tokens-expire', target: '_blank', rel: 'noopener noreferrer'))
= form.gitlab_ui_checkbox_component :service_access_tokens_expiration_enforced, _('Require expiration date'), help_text: safe_format(s_('Changes will not affect existing token expiration dates. %{link_start}How will this affect expiration dates?%{link_end}'), tag_pair(pat_expiry_rules_link, :link_start, :link_end))
- return unless ::Gitlab::Saas.enabled? && group.root?
- return unless License.feature_available?(:service_accounts)
- pat_expiry_rules_link = link_to('', help_page_path('user/profile/personal_access_tokens', anchor: 'when-personal-access-tokens-expire', target: '_blank', rel: 'noopener noreferrer'))
%h5= _('Service access token expiration')
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :service_access_tokens_expiration_enforced, s_('GroupSettings|Service account token expiration'), help_text: safe_format(_('Changes will not affect existing token expiration dates. %{link_start}How will this affect expiration dates?%{link_end}'), tag_pair(pat_expiry_rules_link, :link_start, :link_end)), checkbox_options: { disabled: !can_change_service_access_tokens_expiration?(current_user, group), data: { testid: 'service_access_tokens_expiration_enforced_checkbox' }, checked: group.service_access_tokens_expiration_enforced? }
......@@ -28,6 +28,7 @@ module ApplicationSetting
expose :group_owners_can_manage_default_branch_protection, if: ->(_instance, _opts) { ::License.feature_available?(:default_branch_protection_restriction_in_groups) }
expose :maintenance_mode, if: ->(_instance, _opts) { RegistrationFeatures::MaintenanceMode.feature_available? }
expose :maintenance_mode_message, if: ->(_instance, _opts) { RegistrationFeatures::MaintenanceMode.feature_available? }
expose :service_access_tokens_expiration_enforced, if: ->(_instance, _opts) { ::License.feature_available?(:service_accounts) }
expose :git_two_factor_session_expiry, if: ->(_instance, _opts) { License.feature_available?(:git_two_factor_enforcement) && ::Feature.enabled?(:two_factor_for_cli) }
expose(*EE::ApplicationSettingsHelper.git_abuse_rate_limit_attributes, if: ->(_instance, _options) do
::License.feature_available?(:git_abuse_rate_limit)
......
......@@ -12,6 +12,9 @@ module GroupDetail
expose :shared_runners_minutes_limit
expose :extra_shared_runners_minutes_limit
expose :prevent_forking_outside_group?, as: :prevent_forking_outside_group
expose :service_access_tokens_expiration_enforced?, as: :service_access_tokens_expiration_enforced,
if: ->(group, options) { group.root? && group.licensed_feature_available?(:service_accounts) }
expose :membership_lock?, as: :membership_lock
expose :ip_restriction_ranges, if: ->(group, options) { ip_restriction_feature_available?(group) }
......
......@@ -54,6 +54,9 @@ def update_group(group)
params.delete(:prevent_forking_outside_group) unless
can?(current_user, :change_prevent_group_forking, group)
params.delete(:service_access_tokens_expiration_enforced) unless
group.root? && can?(current_user, :admin_service_accounts, group)
unless group.unique_project_download_limit_enabled?
%i[
unique_project_download_limit
......
......@@ -42,6 +42,9 @@ module GroupsHelpers
optional :ip_restriction_ranges,
type: String,
desc: 'List of IP addresses which need to be restricted for group'
optional :service_access_tokens_expiration_enforced,
type: ::Grape::API::Boolean,
desc: "To enforce token expiration for Service accounts users for group"
end
params :optional_projects_params_ee do
......
......@@ -64,6 +64,7 @@ module SettingsHelpers
optional :auto_ban_user_on_excessive_projects_download, type: Grape::API::Boolean, desc: 'Ban users from the application when they exceed maximum number of unique projects download in the specified time period'
optional :openai_api_key, type: String, desc: "OpenAI API key"
optional :anthropic_api_key, type: String, desc: "Anthropic API key"
optional :service_access_tokens_expiration_enforced, type: Grape::API::Boolean, desc: "To enforce token expiration for Service accounts users"
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment