Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
0d7dcc6f
Commit
0d7dcc6f
authored
Jul 29, 2021
by
Fabio Pitino
Committed by
Stan Hu
Jul 29, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Exempt public/internal projects from job token scope
parent
286935e2
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
65 additions
and
64 deletions
+65
-64
app/policies/project_policy.rb
app/policies/project_policy.rb
+1
-1
doc/api/index.md
doc/api/index.md
+4
-2
spec/policies/project_policy_spec.rb
spec/policies/project_policy_spec.rb
+50
-51
spec/requests/api/generic_packages_spec.rb
spec/requests/api/generic_packages_spec.rb
+1
-1
spec/requests/api/go_proxy_spec.rb
spec/requests/api/go_proxy_spec.rb
+1
-1
spec/requests/api/maven_packages_spec.rb
spec/requests/api/maven_packages_spec.rb
+1
-1
spec/requests/api/npm_project_packages_spec.rb
spec/requests/api/npm_project_packages_spec.rb
+1
-1
spec/requests/api/pypi_packages_spec.rb
spec/requests/api/pypi_packages_spec.rb
+1
-1
spec/requests/api/releases_spec.rb
spec/requests/api/releases_spec.rb
+1
-1
spec/requests/api/rubygem_packages_spec.rb
spec/requests/api/rubygem_packages_spec.rb
+1
-1
spec/requests/api/terraform/modules/v1/packages_spec.rb
spec/requests/api/terraform/modules/v1/packages_spec.rb
+1
-1
spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
...ed_contexts/requests/api/conan_packages_shared_context.rb
+1
-1
spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
...ared_contexts/requests/api/npm_packages_shared_context.rb
+1
-1
No files found.
app/policies/project_policy.rb
View file @
0d7dcc6f
...
@@ -533,7 +533,7 @@ class ProjectPolicy < BasePolicy
...
@@ -533,7 +533,7 @@ class ProjectPolicy < BasePolicy
enable
:read_project_for_iids
enable
:read_project_for_iids
end
end
rule
{
~
project_allowed_for_job_token
}.
prevent_all
rule
{
~
p
ublic_project
&
~
internal_access
&
~
p
roject_allowed_for_job_token
}.
prevent_all
rule
{
can?
(
:public_access
)
}.
policy
do
rule
{
can?
(
:public_access
)
}.
policy
do
enable
:read_package
enable
:read_package
...
...
doc/api/index.md
View file @
0d7dcc6f
...
@@ -259,7 +259,7 @@ Refer to this feature's version history for more details.
...
@@ -259,7 +259,7 @@ Refer to this feature's version history for more details.
You can limit the access scope of a project's CI/CD job token to increase the
You can limit the access scope of a project's CI/CD job token to increase the
job token's security. A job token might give extra permissions that aren't necessary
job token's security. A job token might give extra permissions that aren't necessary
to access specific resources. Limiting the job token access scope reduces the risk of a leaked
to access specific
private
resources. Limiting the job token access scope reduces the risk of a leaked
token being used to access private data that the user associated to the job can access.
token being used to access private data that the user associated to the job can access.
Control the job token access scope with an allowlist of other projects authorized
Control the job token access scope with an allowlist of other projects authorized
...
@@ -273,7 +273,9 @@ setting at all times, and configure the allowlist for cross-project access if ne
...
@@ -273,7 +273,9 @@ setting at all times, and configure the allowlist for cross-project access if ne
For example, when the setting is enabled, jobs in a pipeline in project
`A`
have
For example, when the setting is enabled, jobs in a pipeline in project
`A`
have
a
`CI_JOB_TOKEN`
scope limited to project
`A`
. If the job needs to use the token
a
`CI_JOB_TOKEN`
scope limited to project
`A`
. If the job needs to use the token
to make an API request to project
`B`
, then
`B`
must be added to the allowlist for
`A`
.
to make an API request to a private project
`B`
, then
`B`
must be added to the allowlist for
`A`
.
If project
`B`
is public or internal, it doesn't need to be added to the allowlist.
The job token scope is only for controlling access to private projects.
To enable and configure the job token scope limit:
To enable and configure the job token scope limit:
...
...
spec/policies/project_policy_spec.rb
View file @
0d7dcc6f
...
@@ -1419,66 +1419,65 @@ RSpec.describe ProjectPolicy do
...
@@ -1419,66 +1419,65 @@ RSpec.describe ProjectPolicy do
end
end
describe
'when user is authenticated via CI_JOB_TOKEN'
,
:request_store
do
describe
'when user is authenticated via CI_JOB_TOKEN'
,
:request_store
do
let
(
:current_user
)
{
developer
}
using
RSpec
::
Parameterized
::
TableSyntax
let
(
:job
)
{
build_stubbed
(
:ci_build
,
project:
scope_project
,
user:
current_user
)
}
before
do
current_user
.
set_ci_job_token_scope!
(
job
)
scope_project
.
update!
(
ci_job_token_scope_enabled:
true
)
end
context
'when accessing a private project'
do
let
(
:project
)
{
private_project
}
context
'when the job token comes from the same project'
do
let
(
:scope_project
)
{
project
}
it
{
is_expected
.
to
be_allowed
(
:developer_access
)
}
end
context
'when the job token comes from another project'
do
let
(
:scope_project
)
{
create
(
:project
,
:private
)
}
before
do
scope_project
.
add_developer
(
current_user
)
end
it
{
is_expected
.
to
be_disallowed
(
:guest_access
)
}
context
'when job token scope is disabled'
do
before
do
scope_project
.
update!
(
ci_job_token_scope_enabled:
false
)
end
it
{
is_expected
.
to
be_allowed
(
:guest_access
)
}
where
(
:project_visibility
,
:user_role
,
:external_user
,
:scope_project_type
,
:token_scope_enabled
,
:result
)
do
end
:private
|
:reporter
|
false
|
:same
|
true
|
true
:private
|
:reporter
|
false
|
:same
|
false
|
true
:private
|
:reporter
|
false
|
:different
|
true
|
false
:private
|
:reporter
|
false
|
:different
|
false
|
true
:private
|
:guest
|
false
|
:same
|
true
|
true
:private
|
:guest
|
false
|
:same
|
false
|
true
:private
|
:guest
|
false
|
:different
|
true
|
false
:private
|
:guest
|
false
|
:different
|
false
|
true
:internal
|
:reporter
|
false
|
:same
|
true
|
true
:internal
|
:reporter
|
true
|
:same
|
true
|
true
:internal
|
:reporter
|
false
|
:same
|
false
|
true
:internal
|
:reporter
|
false
|
:different
|
true
|
true
:internal
|
:reporter
|
true
|
:different
|
true
|
false
:internal
|
:reporter
|
false
|
:different
|
false
|
true
:internal
|
:guest
|
false
|
:same
|
true
|
true
:internal
|
:guest
|
true
|
:same
|
true
|
true
:internal
|
:guest
|
false
|
:same
|
false
|
true
:internal
|
:guest
|
false
|
:different
|
true
|
true
:internal
|
:guest
|
true
|
:different
|
true
|
false
:internal
|
:guest
|
false
|
:different
|
false
|
true
:public
|
:reporter
|
false
|
:same
|
true
|
true
:public
|
:reporter
|
false
|
:same
|
false
|
true
:public
|
:reporter
|
false
|
:different
|
true
|
true
:public
|
:reporter
|
false
|
:different
|
false
|
true
:public
|
:guest
|
false
|
:same
|
true
|
true
:public
|
:guest
|
false
|
:same
|
false
|
true
:public
|
:guest
|
false
|
:different
|
true
|
true
:public
|
:guest
|
false
|
:different
|
false
|
true
end
end
end
context
'when accessing a public project'
do
let
(
:project
)
{
public_project
}
context
'when the job token comes from the same project'
do
with_them
do
let
(
:scope_project
)
{
project
}
let
(
:current_user
)
{
public_send
(
user_role
)
}
let
(
:project
)
{
public_send
(
"
#{
project_visibility
}
_project"
)
}
let
(
:job
)
{
build_stubbed
(
:ci_build
,
project:
scope_project
,
user:
current_user
)
}
it
{
is_expected
.
to
be_allowed
(
:developer_access
)
}
let
(
:scope_project
)
do
if
scope_project_type
==
:same
project
else
create
(
:project
,
:private
)
end
end
context
'when the job token comes from another project'
do
let
(
:scope_project
)
{
create
(
:project
,
:private
)
}
before
do
scope_project
.
add_developer
(
current_user
)
end
end
it
{
is_expected
.
to
be_disallowed
(
:public_access
)
}
context
'when job token scope is disabled'
do
before
do
before
do
scope_project
.
update!
(
ci_job_token_scope_enabled:
false
)
current_user
.
set_ci_job_token_scope!
(
job
)
current_user
.
external
=
external_user
scope_project
.
update!
(
ci_job_token_scope_enabled:
token_scope_enabled
)
end
end
it
{
is_expected
.
to
be_allowed
(
:public_access
)
}
it
"enforces the expected permissions"
do
if
result
is_expected
.
to
be_allowed
(
"
#{
user_role
}
_access"
.
to_sym
)
else
is_expected
.
to
be_disallowed
(
"
#{
user_role
}
_access"
.
to_sym
)
end
end
end
end
end
end
...
...
spec/requests/api/generic_packages_spec.rb
View file @
0d7dcc6f
...
@@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
...
@@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
let_it_be
(
:project_deploy_token_wo
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token_wo
,
project:
project
)
}
let_it_be
(
:project_deploy_token_wo
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token_wo
,
project:
project
)
}
let
(
:user
)
{
personal_access_token
.
user
}
let
(
:user
)
{
personal_access_token
.
user
}
let
(
:ci_build
)
{
create
(
:ci_build
,
:running
,
user:
user
,
project:
project
)
}
let
(
:ci_build
)
{
create
(
:ci_build
,
:running
,
user:
user
)
}
let
(
:snowplow_standard_context_params
)
{
{
user:
user
,
project:
project
,
namespace:
project
.
namespace
}
}
let
(
:snowplow_standard_context_params
)
{
{
user:
user
,
project:
project
,
namespace:
project
.
namespace
}
}
def
auth_header
def
auth_header
...
...
spec/requests/api/go_proxy_spec.rb
View file @
0d7dcc6f
...
@@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
...
@@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
let_it_be
(
:base
)
{
"
#{
Settings
.
build_gitlab_go_url
}
/
#{
project
.
full_path
}
"
}
let_it_be
(
:base
)
{
"
#{
Settings
.
build_gitlab_go_url
}
/
#{
project
.
full_path
}
"
}
let_it_be
(
:oauth
)
{
create
:oauth_access_token
,
scopes:
'api'
,
resource_owner:
user
}
let_it_be
(
:oauth
)
{
create
:oauth_access_token
,
scopes:
'api'
,
resource_owner:
user
}
let_it_be
(
:job
)
{
create
:ci_build
,
user:
user
,
status: :running
,
project:
project
}
let_it_be
(
:job
)
{
create
:ci_build
,
user:
user
,
status: :running
}
let_it_be
(
:pa_token
)
{
create
:personal_access_token
,
user:
user
}
let_it_be
(
:pa_token
)
{
create
:personal_access_token
,
user:
user
}
let_it_be
(
:modules
)
do
let_it_be
(
:modules
)
do
...
...
spec/requests/api/maven_packages_spec.rb
View file @
0d7dcc6f
...
@@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
...
@@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
let_it_be
(
:package_file
)
{
package
.
package_files
.
with_file_name_like
(
'%.xml'
).
first
}
let_it_be
(
:package_file
)
{
package
.
package_files
.
with_file_name_like
(
'%.xml'
).
first
}
let_it_be
(
:jar_file
)
{
package
.
package_files
.
with_file_name_like
(
'%.jar'
).
first
}
let_it_be
(
:jar_file
)
{
package
.
package_files
.
with_file_name_like
(
'%.jar'
).
first
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:job
,
reload:
true
)
{
create
(
:ci_build
,
user:
user
,
status: :running
,
project:
project
)
}
let_it_be
(
:job
,
reload:
true
)
{
create
(
:ci_build
,
user:
user
,
status: :running
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:deploy_token_for_group
)
{
create
(
:deploy_token
,
:group
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token_for_group
)
{
create
(
:deploy_token
,
:group
,
read_package_registry:
true
,
write_package_registry:
true
)
}
...
...
spec/requests/api/npm_project_packages_spec.rb
View file @
0d7dcc6f
...
@@ -78,7 +78,7 @@ RSpec.describe API::NpmProjectPackages do
...
@@ -78,7 +78,7 @@ RSpec.describe API::NpmProjectPackages do
context
'with a job token for a different user'
do
context
'with a job token for a different user'
do
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be_with_reload
(
:other_job
)
{
create
(
:ci_build
,
:running
,
user:
other_user
,
project:
project
)
}
let_it_be_with_reload
(
:other_job
)
{
create
(
:ci_build
,
:running
,
user:
other_user
)
}
let
(
:headers
)
{
build_token_auth_header
(
other_job
.
token
)
}
let
(
:headers
)
{
build_token_auth_header
(
other_job
.
token
)
}
...
...
spec/requests/api/pypi_packages_spec.rb
View file @
0d7dcc6f
...
@@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
...
@@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
,
project:
project
)
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
)
}
let
(
:headers
)
{
{}
}
let
(
:headers
)
{
{}
}
...
...
spec/requests/api/releases_spec.rb
View file @
0d7dcc6f
...
@@ -811,7 +811,7 @@ RSpec.describe API::Releases do
...
@@ -811,7 +811,7 @@ RSpec.describe API::Releases do
end
end
context
'when using JOB-TOKEN auth'
do
context
'when using JOB-TOKEN auth'
do
let
(
:job
)
{
create
(
:ci_build
,
user:
maintainer
,
project:
project
)
}
let
(
:job
)
{
create
(
:ci_build
,
user:
maintainer
)
}
let
(
:params
)
do
let
(
:params
)
do
{
{
name:
'Another release'
,
name:
'Another release'
,
...
...
spec/requests/api/rubygem_packages_spec.rb
View file @
0d7dcc6f
...
@@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
...
@@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
let_it_be_with_reload
(
:project
)
{
create
(
:project
)
}
let_it_be_with_reload
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
)
}
let_it_be
(
:user
)
{
personal_access_token
.
user
}
let_it_be
(
:user
)
{
personal_access_token
.
user
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
,
project:
project
)
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:headers
)
{
{}
}
let_it_be
(
:headers
)
{
{}
}
...
...
spec/requests/api/terraform/modules/v1/packages_spec.rb
View file @
0d7dcc6f
...
@@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
...
@@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let_it_be
(
:package
)
{
create
(
:terraform_module_package
,
project:
project
)
}
let_it_be
(
:package
)
{
create
(
:terraform_module_package
,
project:
project
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
)
}
let_it_be
(
:user
)
{
personal_access_token
.
user
}
let_it_be
(
:user
)
{
personal_access_token
.
user
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
,
project:
project
)
}
let_it_be
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
...
...
spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
View file @
0d7dcc6f
...
@@ -11,7 +11,7 @@ RSpec.shared_context 'conan api setup' do
...
@@ -11,7 +11,7 @@ RSpec.shared_context 'conan api setup' do
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let
(
:project
)
{
package
.
project
}
let
(
:project
)
{
package
.
project
}
let
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
,
project:
project
)
}
let
(
:job
)
{
create
(
:ci_build
,
:running
,
user:
user
)
}
let
(
:job_token
)
{
job
.
token
}
let
(
:job_token
)
{
job
.
token
}
let
(
:auth_token
)
{
personal_access_token
.
token
}
let
(
:auth_token
)
{
personal_access_token
.
token
}
let
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
...
...
spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
View file @
0d7dcc6f
...
@@ -11,7 +11,7 @@ RSpec.shared_context 'npm api setup' do
...
@@ -11,7 +11,7 @@ RSpec.shared_context 'npm api setup' do
let_it_be
(
:package
,
reload:
true
)
{
create
(
:npm_package
,
project:
project
,
name:
"@
#{
group
.
path
}
/scoped_package"
)
}
let_it_be
(
:package
,
reload:
true
)
{
create
(
:npm_package
,
project:
project
,
name:
"@
#{
group
.
path
}
/scoped_package"
)
}
let_it_be
(
:token
)
{
create
(
:oauth_access_token
,
scopes:
'api'
,
resource_owner:
user
)
}
let_it_be
(
:token
)
{
create
(
:oauth_access_token
,
scopes:
'api'
,
resource_owner:
user
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:job
,
reload:
true
)
{
create
(
:ci_build
,
user:
user
,
status: :running
,
project:
project
)
}
let_it_be
(
:job
,
reload:
true
)
{
create
(
:ci_build
,
user:
user
,
status: :running
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:deploy_token
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token
,
project:
project
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment