Class: Ci::JobToken::Authorization
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- ApplicationRecord
- Ci::JobToken::Authorization
- Extended by:
- Gitlab::InternalEventsTracking
- Includes:
- EachBatch
- Defined in:
- app/models/ci/job_token/authorization.rb
Constant Summary collapse
- REQUEST_CACHE_KEY =
:job_token_authorizations- CAPTURE_DELAY =
5.minutes
- AUTHORIZATION_ROW_LIMIT =
1000
Constants inherited from ApplicationRecord
Constants included from HasCheckConstraints
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
Constants included from ResetOnColumnErrors
ResetOnColumnErrors::MAX_RESET_PERIOD
Class Method Summary collapse
- .add_to_request_store_hash(hash) ⇒ Object
-
.capture(origin_project:, accessed_project:) ⇒ Object
Record in SafeRequestStore a cross-project access attempt.
- .capture_job_token_policies(policies) ⇒ Object
- .captured_authorizations ⇒ Object
- .log_captures!(accessed_project_id:, origin_project_id:, policies: []) ⇒ Object
-
.log_captures_async ⇒ Object
Schedule logging of captured authorizations in a background worker.
Methods included from Gitlab::InternalEventsTracking
Methods inherited from ApplicationRecord
Methods inherited from ApplicationRecord
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
Methods included from Organizations::Sharding
Methods included from ResetOnColumnErrors
#reset_on_union_error, #reset_on_unknown_attribute_error
Methods included from Gitlab::SensitiveSerializableHash
Class Method Details
.add_to_request_store_hash(hash) ⇒ Object
100 101 102 103 |
# File 'app/models/ci/job_token/authorization.rb', line 100 def self.add_to_request_store_hash(hash) new_hash = .present? ? .merge(hash) : hash Gitlab::SafeRequestStore[REQUEST_CACHE_KEY] = new_hash end |
.capture(origin_project:, accessed_project:) ⇒ Object
Record in SafeRequestStore a cross-project access attempt
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'app/models/ci/job_token/authorization.rb', line 39 def self.capture(origin_project:, accessed_project:) label = origin_project == accessed_project ? 'same-project' : 'cross-project' track_internal_event( 'authorize_job_token_with_disabled_scope', project: accessed_project, additional_properties: { label: label } ) # We are tracking ci job token access to project resources, but we # are not yet persisting this log until a request successfully # completes. We will do that in a middleware. This is because the policy # rule about job token scope may be satisfied but a subsequent rule in # the Declarative Policies may block the authorization. add_to_request_store_hash(accessed_project_id: accessed_project.id, origin_project_id: origin_project.id) end |
.capture_job_token_policies(policies) ⇒ Object
57 58 59 |
# File 'app/models/ci/job_token/authorization.rb', line 57 def self.capture_job_token_policies(policies) add_to_request_store_hash(policies: policies) end |
.captured_authorizations ⇒ Object
105 106 107 |
# File 'app/models/ci/job_token/authorization.rb', line 105 def self. Gitlab::SafeRequestStore[REQUEST_CACHE_KEY] end |
.log_captures!(accessed_project_id:, origin_project_id:, policies: []) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'app/models/ci/job_token/authorization.rb', line 78 def self.log_captures!(accessed_project_id:, origin_project_id:, policies: []) current_time = Time.current attributes = { accessed_project_id: accessed_project_id, origin_project_id: origin_project_id, last_authorized_at: current_time } transaction do if policies.present? auth_log = lock.find_by( accessed_project_id: accessed_project_id, origin_project_id: origin_project_id ) policies = policies.index_with(current_time) attributes[:job_token_policies] = auth_log ? auth_log.job_token_policies.merge(policies) : policies end upsert(attributes, unique_by: [:accessed_project_id, :origin_project_id], on_duplicate: :update) end end |
.log_captures_async ⇒ Object
Schedule logging of captured authorizations in a background worker. We add a 5 minutes delay with deduplication logic so that we log the same authorization at most every 5 minutes. Otherwise, in high traffic projects we could be logging authorizations very frequently.
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'app/models/ci/job_token/authorization.rb', line 65 def self.log_captures_async = return unless accessed_project_id = [:accessed_project_id] origin_project_id = [:origin_project_id] return unless accessed_project_id && origin_project_id policies = .fetch(:policies, []).map(&:to_s) Ci::JobToken::LogAuthorizationWorker # rubocop:disable CodeReuse/Worker -- This method is called from a middleware and it's better tested .perform_in(CAPTURE_DELAY, accessed_project_id, origin_project_id, policies) end |