Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
332 commits
Select commit Hold shift + click to select a range
f5d4ce6
compile errors
Excellencedev Jan 5, 2026
012c9e0
...
Excellencedev Jan 5, 2026
b37a967
logs
Excellencedev Jan 5, 2026
15c19f6
...
Excellencedev Jan 5, 2026
350bcab
fix bug
Excellencedev Jan 5, 2026
d262948
Merge branch 'main' into fix-24635
Excellencedev Jan 6, 2026
9610d7f
Implement all requested changes
Excellencedev Jan 6, 2026
b4a17df
lints
Excellencedev Jan 6, 2026
3fb03fb
lint
Excellencedev Jan 6, 2026
dcf43af
fix ui issues
Excellencedev Jan 6, 2026
ba3a3a7
Feedback
Excellencedev Jan 7, 2026
655733e
fix
Excellencedev Jan 7, 2026
28dff2a
update parser
Excellencedev Jan 7, 2026
43931dc
refactor the parser
Excellencedev Jan 7, 2026
a5debd9
add releases and projects units
Excellencedev Jan 7, 2026
f8a0b25
resolve todo
Excellencedev Jan 7, 2026
1dfc172
fixes
Excellencedev Jan 7, 2026
1840f0a
formatting issues
Excellencedev Jan 7, 2026
7364953
...
Excellencedev Jan 7, 2026
4e524d3
improve comments
Excellencedev Jan 8, 2026
79c38fe
Merge branch 'main' into fix-24635
Excellencedev Jan 11, 2026
f7fc879
Merge branch 'main' into fix-24635
Excellencedev Jan 16, 2026
feb791c
feedback fixes
Excellencedev Jan 16, 2026
7cccb84
fixes
Excellencedev Jan 16, 2026
6d14a69
ui fixes
Excellencedev Jan 16, 2026
87d9f86
Merge branch 'main' into fix-24635
Excellencedev Jan 16, 2026
01a328b
fixes
Excellencedev Jan 16, 2026
5067f1d
fixes
Excellencedev Jan 16, 2026
27a4055
fix
Excellencedev Jan 16, 2026
2317080
logs
Excellencedev Jan 16, 2026
130b94b
..
Excellencedev Jan 16, 2026
4ed81fe
fix
Excellencedev Jan 17, 2026
a8c2d13
refactor ui
Excellencedev Jan 17, 2026
068ef6d
lints
Excellencedev Jan 17, 2026
1934c55
Merge branch 'main' into fix-24635
Excellencedev Jan 17, 2026
9352cc2
update test
Excellencedev Jan 17, 2026
493d51d
fix test
Excellencedev Jan 17, 2026
b6bf0a1
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Jan 17, 2026
c770087
fix formatting
Excellencedev Jan 17, 2026
2480c30
CrossRepoMode
Excellencedev Jan 17, 2026
f5c5775
CrossRepoMode tests
Excellencedev Jan 17, 2026
77871ef
fixes
Excellencedev Jan 18, 2026
c9ea591
format
Excellencedev Jan 18, 2026
4410d73
use ToString
Excellencedev Jan 18, 2026
ef139fa
Merge branch 'main' into fix-24635
Excellencedev Jan 24, 2026
57d8b82
readd migration
Excellencedev Jan 24, 2026
0d63aa8
...
Excellencedev Jan 24, 2026
33ef56e
lints
Excellencedev Jan 24, 2026
f7a4406
copyright
Excellencedev Jan 24, 2026
a7c2c96
fix saving issue
Excellencedev Jan 24, 2026
574d317
Update models/migrations/migrations.go
ChristopherHX Jan 25, 2026
883d652
patch-1
Excellencedev Jan 25, 2026
493f133
patch-2
Excellencedev Jan 25, 2026
1de6d43
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Jan 25, 2026
440cfa1
fmt
Excellencedev Jan 25, 2026
e0c5381
Update models/migrations/v1_26/V326.go
Excellencedev Jan 31, 2026
cee21ad
Update tests/integration/actions_persistence_test.go
Excellencedev Jan 31, 2026
916806c
Update routers/web/org/setting/actions.go
Excellencedev Jan 31, 2026
2107fd6
Update routers/api/packages/api.go
Excellencedev Jan 31, 2026
f5c4c33
Update routers/api/v1/repo/file.go
Excellencedev Jan 31, 2026
005de17
Address Copilot review
Excellencedev Jan 31, 2026
7636c6c
remove actionsperm
Excellencedev Jan 31, 2026
2096877
fmt
Excellencedev Jan 31, 2026
f08356b
Merge branch 'main' into fix-24635
Excellencedev Feb 1, 2026
a2b88d6
ActionsTaskID
Excellencedev Feb 1, 2026
75023da
missing imports
Excellencedev Feb 1, 2026
ea981c2
fmt
Excellencedev Feb 1, 2026
6a7c528
Merge branch 'main' into fix-24635
Excellencedev Feb 6, 2026
a59b428
f8xes from feedback
Excellencedev Feb 6, 2026
d3fa0ec
update refernces
Excellencedev Feb 7, 2026
e2c14de
Merge branch 'main' into fix-24635
Excellencedev Feb 7, 2026
0912b12
fix lint
Excellencedev Feb 7, 2026
b95361c
extra blank lines
Excellencedev Feb 7, 2026
a2fc97a
Fix comment
ChristopherHX Feb 7, 2026
5c3493f
logic fixes
ChristopherHX Feb 7, 2026
9425be4
cross repo package access respect permission none and require package…
ChristopherHX Feb 7, 2026
0a3049a
revert, packages_model.Type(ctx.PathParam("type")) does not work
ChristopherHX Feb 7, 2026
fd0aed3
Refactor repo_permissions to repect none permission
ChristopherHX Feb 7, 2026
137efea
Store Readonly in database for PR from forks
ChristopherHX Feb 7, 2026
b04f759
refactor functions Effective => Default / no fork param
ChristopherHX Feb 7, 2026
c2045d2
Allow public read for public repos
ChristopherHX Feb 7, 2026
fc57605
clamp pr from fork
ChristopherHX Feb 7, 2026
d8ce6d9
Refactor Simplify broken container permission checks
ChristopherHX Feb 7, 2026
fc1620c
update tests
ChristopherHX Feb 7, 2026
455dfbb
Fix lint
ChristopherHX Feb 7, 2026
a6b5417
spelling
ChristopherHX Feb 7, 2026
e91e7ee
Merge branch 'main' into fix-24635
Excellencedev Feb 8, 2026
aba7f66
Actions package permissions
ChristopherHX Feb 9, 2026
42e9a6d
fix grantMode for private org
ChristopherHX Feb 9, 2026
50405cb
fix typo
ChristopherHX Feb 9, 2026
8736615
fix pkg type pub
ChristopherHX Feb 9, 2026
eed2ad9
fix code
ChristopherHX Feb 9, 2026
1806b29
fix lint
ChristopherHX Feb 9, 2026
9c01831
remove test stub
ChristopherHX Feb 9, 2026
56486b8
Revert "remove test stub"
ChristopherHX Feb 9, 2026
ae81b00
Revert Broken Package Access + single test
ChristopherHX Feb 9, 2026
9ce2472
add missing return
ChristopherHX Feb 9, 2026
6b4ed50
Merge branch 'main' into fix-24635
silverwind Feb 12, 2026
b4c61a4
Merge branch 'main' into fix-24635
Excellencedev Feb 13, 2026
08063e7
Apply suggestion from @silverwind
silverwind Feb 13, 2026
3e3e081
Update routers/private/hook_pre_receive.go
Excellencedev Feb 13, 2026
c9999c4
Address feedbac
Excellencedev Feb 14, 2026
ca6b32f
next
Excellencedev Feb 14, 2026
9e7db02
..
Excellencedev Feb 14, 2026
04299c9
fmt
Excellencedev Feb 14, 2026
7755c83
Refactor Cross-Repo Permission Logic
Excellencedev Feb 15, 2026
d7a8957
revert pacage.go
Excellencedev Feb 15, 2026
a8b9575
update the permission parser tests to include the projects scope
Excellencedev Feb 15, 2026
c636e81
bug
Excellencedev Feb 15, 2026
f9a64b6
simplify code
Zettat123 Feb 15, 2026
2d9794b
Merge pull request #2 from Zettat123/improve-token-perms-check
Excellencedev Feb 16, 2026
c684dd9
Merge branch 'main' into fix-24635
silverwind Feb 16, 2026
42fcef9
remove .CsrfTokenHtml
silverwind Feb 16, 2026
e17a531
address silverwind review
Excellencedev Feb 16, 2026
ddbc47a
Revert "remove .CsrfTokenHtml"
Excellencedev Feb 16, 2026
e6d5e82
Revert "address silverwind review"
Excellencedev Feb 16, 2026
18f8247
Reapply "remove .CsrfTokenHtml"
Excellencedev Feb 16, 2026
c31ebf6
...
Excellencedev Feb 16, 2026
89a6783
...
Excellencedev Feb 16, 2026
b7a92b8
...
Excellencedev Feb 17, 2026
d1126e9
fix tests
Excellencedev Feb 17, 2026
b1d1c64
Apply suggestion from @silverwind
silverwind Feb 17, 2026
214424c
Apply suggestion from @silverwind
silverwind Feb 17, 2026
ae62bad
Apply suggestion from @silverwind
silverwind Feb 17, 2026
3411280
Apply suggestion from @silverwind
silverwind Feb 17, 2026
ea4a284
Apply suggestion from @silverwind
silverwind Feb 17, 2026
8ea2cbd
Apply suggestion from @silverwind
silverwind Feb 17, 2026
381bc93
silverwind review
Excellencedev Feb 17, 2026
018339e
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Feb 17, 2026
ebed469
Fix build error: uncomment ActionsTokenPermissionModeCustom constant
silverwind Feb 17, 2026
618e21e
unt
Excellencedev Feb 17, 2026
b66c331
remove
Excellencedev Feb 17, 2026
8caf9e4
unused
Excellencedev Feb 17, 2026
6333714
Merge branch 'main' into fix-24635
Excellencedev Feb 17, 2026
8770d0b
newline
Excellencedev Feb 17, 2026
ed525fa
Merge branch 'main' into fix-24635
silverwind Feb 18, 2026
f0fc5a2
cleanup
Excellencedev Feb 19, 2026
ed80060
fmt
Excellencedev Feb 19, 2026
481b9ca
test
Excellencedev Feb 19, 2026
61c8bda
cleanup
Excellencedev Feb 19, 2026
b097095
cleanup
Excellencedev Feb 19, 2026
20ad9de
FEEDBACK
Excellencedev Feb 21, 2026
cb93b4b
lnt
Excellencedev Feb 21, 2026
f386234
Merge branch 'main' into fix-24635
silverwind Feb 22, 2026
2efe144
Fix form alignment in actions general settings shared template
silverwind Feb 22, 2026
0498df7
Fix review findings for actions token permissions
silverwind Feb 22, 2026
6110201
Extract shared permissions table template to reduce duplication
silverwind Feb 22, 2026
0bbafb6
Validate stored ActionsTokenPermissionMode against known values
silverwind Feb 22, 2026
2eb2044
Fix default cross-repo access mode to allow access by default
silverwind Feb 22, 2026
827c278
Merge branch 'main' into fix-24635
Excellencedev Feb 22, 2026
0dac17a
Merge branch 'main' into fix-24635
Excellencedev Feb 23, 2026
41c1d97
Latest feedback
Excellencedev Feb 23, 2026
c933f1c
com errors
Excellencedev Feb 23, 2026
9cc110f
fx
Excellencedev Feb 23, 2026
e9c5382
fx
Excellencedev Feb 23, 2026
b325f3e
Merge branch 'main' into fix-24635
Excellencedev Feb 23, 2026
0880942
add docs
Excellencedev Feb 23, 2026
5b7d7a5
doc changes
Excellencedev Feb 23, 2026
b1acdc2
last changes
Excellencedev Feb 23, 2026
9d2f890
feedback
Excellencedev Feb 28, 2026
195ee7d
err
Excellencedev Feb 28, 2026
9b95e0a
test
Excellencedev Feb 28, 2026
0427102
changes
Excellencedev Mar 1, 2026
81d4263
Merge branch 'main' into fix-24635
Excellencedev Mar 3, 2026
2084180
feedbac
Excellencedev Mar 3, 2026
b7f6bba
evrythng
Excellencedev Mar 5, 2026
17cc432
refactor
wxiaoguang Mar 5, 2026
ca2b627
clean up
wxiaoguang Mar 5, 2026
3eef9ed
clean up
Excellencedev Mar 5, 2026
85c4bef
remove fallback
Excellencedev Mar 5, 2026
400ab94
update document for packages permission
wxiaoguang Mar 5, 2026
393f9c4
refactor
wxiaoguang Mar 5, 2026
6a9dcb3
revert
wxiaoguang Mar 5, 2026
d2245c1
fix lint
wxiaoguang Mar 5, 2026
4cc1c1c
change
Excellencedev Mar 6, 2026
85d8431
change
Excellencedev Mar 6, 2026
952510a
Merge branch 'main' into fix-24635
Excellencedev Mar 6, 2026
d755ad4
fixes
Zettat123 Mar 6, 2026
1633d7b
fix test
Zettat123 Mar 6, 2026
1e439da
fix db query
Zettat123 Mar 6, 2026
7da98cc
check target repo config
Zettat123 Mar 7, 2026
290b2ce
new test
Excellencedev Mar 7, 2026
00b9f0f
fmt
Excellencedev Mar 7, 2026
bd7e748
fx test
Excellencedev Mar 7, 2026
1974c31
change
Excellencedev Mar 7, 2026
d7cf2b9
.
Excellencedev Mar 7, 2026
dd25d16
.
Excellencedev Mar 7, 2026
d22a375
Merge branch 'main' into fix-24635
silverwind Mar 10, 2026
0641565
Fix actions token permission bugs found during review
silverwind Mar 10, 2026
b9012fd
do not use GetXxx
wxiaoguang Mar 10, 2026
dd4f6f4
split actions unit config and rename vars
wxiaoguang Mar 11, 2026
f200c1d
merge git push env
wxiaoguang Mar 11, 2026
e32e37f
merge git push env
wxiaoguang Mar 11, 2026
5c6ae7e
remove ActionsCrossRepoMode=all (confusing and will be abused), clean up
wxiaoguang Mar 11, 2026
c6bb15c
dead translation
wxiaoguang Mar 11, 2026
109dc10
fix text
wxiaoguang Mar 11, 2026
c39b98f
Merge branch 'main' into fix-24635
Excellencedev Mar 11, 2026
01a6ce8
conflct
Excellencedev Mar 11, 2026
2f2bd8d
delete
Excellencedev Mar 11, 2026
1dce09b
conflct
Excellencedev Mar 11, 2026
d29f20c
fmt
Excellencedev Mar 11, 2026
2e4a779
26
Excellencedev Mar 11, 2026
ed82dff
address feedback
Excellencedev Mar 11, 2026
753d8c8
.
Excellencedev Mar 11, 2026
fda2362
changes
Excellencedev Mar 13, 2026
4bdecd2
fx tests
Excellencedev Mar 13, 2026
57e1288
Handle Nil Doer in Pushing Environment
Excellencedev Mar 13, 2026
fd8db9f
Fixing Test Failure
Excellencedev Mar 13, 2026
952fb03
fmt
Excellencedev Mar 13, 2026
824ed3c
Merge branch 'main' into fix-24635
wxiaoguang Mar 13, 2026
65ccecf
comment
Excellencedev Mar 13, 2026
0ea45c2
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Mar 13, 2026
8a54bcd
Update modules/repository/env.go
wxiaoguang Mar 13, 2026
b362a2a
fix git http push env
wxiaoguang Mar 13, 2026
dda0dff
remove duplicate EnvRepoID, it has already been set in DoerPushingEnv…
wxiaoguang Mar 13, 2026
5b38323
Update models/perm/access/repo_permission.go
Excellencedev Mar 13, 2026
3278b5e
Update models/perm/access/repo_permission.go
Excellencedev Mar 13, 2026
2a6f60d
fix test, that asserted now unexpected behavior
ChristopherHX Mar 13, 2026
0716eeb
WIP
Excellencedev Mar 14, 2026
183692c
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Mar 14, 2026
5a7bfdb
Merge branch 'main' into feature-actions-permission
wxiaoguang Mar 14, 2026
b7a91a7
refactor
wxiaoguang Mar 14, 2026
278bf61
fix layout bugs
wxiaoguang Mar 14, 2026
1e6fa1b
fix test
wxiaoguang Mar 14, 2026
1e1e1bf
fix test
wxiaoguang Mar 14, 2026
cb2a88a
fix test
wxiaoguang Mar 14, 2026
c989cd0
clean up
wxiaoguang Mar 14, 2026
172b18f
reformat doc
wxiaoguang Mar 14, 2026
8a268e9
fix migration
wxiaoguang Mar 14, 2026
aebde5e
fix unrelated repos bug
Excellencedev Mar 14, 2026
35a91b9
fine tune help text
wxiaoguang Mar 14, 2026
5b40171
fix layout
wxiaoguang Mar 14, 2026
598530b
fine tune help text
wxiaoguang Mar 14, 2026
4bb177f
fix tr key
wxiaoguang Mar 14, 2026
459d6de
show correct permission table inherited from owner
wxiaoguang Mar 14, 2026
0975485
do not render Actions Token Permissions if Actions is disabled
wxiaoguang Mar 14, 2026
b10db5d
change
Excellencedev Mar 14, 2026
46f9ad1
Merge branch 'fix-24635' of https://github.com/Excellencedev/gitea in…
Excellencedev Mar 14, 2026
eacdd04
remove useless attribute
Excellencedev Mar 14, 2026
bb64b07
Migration fix
Excellencedev Mar 15, 2026
e1d11ae
fix form
wxiaoguang Mar 16, 2026
ade5a6c
use explicit var name
wxiaoguang Mar 16, 2026
09454d7
Merge branch 'main' into feature-actions-permission
wxiaoguang Mar 17, 2026
f84981d
fix merge
wxiaoguang Mar 17, 2026
eb4ead7
fix tests
wxiaoguang Mar 17, 2026
9950752
fix tests
wxiaoguang Mar 17, 2026
c556da0
fix tests
wxiaoguang Mar 17, 2026
4ac9a9c
fix tests
wxiaoguang Mar 17, 2026
319fb31
Merge branch 'main' into fix-24635
lunny Mar 21, 2026
6aeda11
Merge branch 'main' into fix-24635
GiteaBot Mar 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions models/perm/access/repo_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,18 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito
return perm, err
}

var accessMode perm_model.AccessMode
if err := repo.LoadUnits(ctx); err != nil {
return perm, err
}

actionsUnit := repo.MustGetUnit(ctx, unit.TypeActions)
actionsCfg := actionsUnit.ActionsConfig()

if task.RepoID != repo.ID {
Comment thread
ChristopherHX marked this conversation as resolved.
taskRepo, exist, err := db.GetByID[repo_model.Repository](ctx, task.RepoID)
if err != nil || !exist {
return perm, err
}
actionsCfg := repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
if !actionsCfg.IsCollaborativeOwner(taskRepo.OwnerID) || !taskRepo.IsPrivate {
// The task repo can access the current repo only if the task repo is private and
// the owner of the task repo is a collaborative owner of the current repo.
Expand All @@ -288,17 +293,33 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito
perm.AccessMode = min(perm.AccessMode, perm_model.AccessModeRead)
return perm, nil
}
accessMode = perm_model.AccessModeRead
} else if task.IsForkPullRequest {
accessMode = perm_model.AccessModeRead
} else {
accessMode = perm_model.AccessModeWrite
// Cross-repo access is always read-only
perm.SetUnitsWithDefaultAccessMode(repo.Units, perm_model.AccessModeRead)
return perm, nil
}

if err := repo.LoadUnits(ctx); err != nil {
return perm, err
// Get effective token permissions from repository settings
effectivePerms := actionsCfg.GetEffectiveTokenPermissions(task.IsForkPullRequest)

// Set up per-unit access modes based on configured permissions
perm.units = repo.Units
perm.unitsMode = make(map[unit.Type]perm_model.AccessMode)
perm.unitsMode[unit.TypeCode] = effectivePerms.Contents
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
perm.unitsMode[unit.TypeIssues] = effectivePerms.Issues
perm.unitsMode[unit.TypePullRequests] = effectivePerms.PullRequests
perm.unitsMode[unit.TypePackages] = effectivePerms.Packages
perm.unitsMode[unit.TypeActions] = effectivePerms.Actions
perm.unitsMode[unit.TypeWiki] = effectivePerms.Wiki

Comment thread
Excellencedev marked this conversation as resolved.
Outdated
// Set base access mode to the maximum of all unit permissions
maxMode := perm_model.AccessModeNone
for _, mode := range perm.unitsMode {
if mode > maxMode {
maxMode = mode
}
}
perm.SetUnitsWithDefaultAccessMode(repo.Units, accessMode)
perm.AccessMode = maxMode

return perm, nil
}

Expand Down
120 changes: 120 additions & 0 deletions models/repo/repo_unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,78 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
return MergeStyleMerge
}

// ActionsTokenPermissionMode defines the default permission mode for Actions tokens
type ActionsTokenPermissionMode string

const (
// ActionsTokenPermissionModePermissive - write access by default (current behavior, backwards compatible)
ActionsTokenPermissionModePermissive ActionsTokenPermissionMode = "permissive"
// ActionsTokenPermissionModeRestricted - read access by default
ActionsTokenPermissionModeRestricted ActionsTokenPermissionMode = "restricted"
)

// ActionsTokenPermissions defines the permissions for different repository units
type ActionsTokenPermissions struct {
// Contents (repository code) - read/write/none
Contents perm.AccessMode `json:"contents"`
// Issues - read/write/none
Issues perm.AccessMode `json:"issues"`
// PullRequests - read/write/none
PullRequests perm.AccessMode `json:"pull_requests"`
// Packages - read/write/none
Packages perm.AccessMode `json:"packages"`
// Actions - read/write/none
Actions perm.AccessMode `json:"actions"`
// Wiki - read/write/none
Wiki perm.AccessMode `json:"wiki"`
}

// DefaultActionsTokenPermissions returns the default permissions for permissive mode
func DefaultActionsTokenPermissions(mode ActionsTokenPermissionMode) ActionsTokenPermissions {
if mode == ActionsTokenPermissionModeRestricted {
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
return ActionsTokenPermissions{
Contents: perm.AccessModeRead,
Issues: perm.AccessModeRead,
PullRequests: perm.AccessModeRead,
Packages: perm.AccessModeRead,
Actions: perm.AccessModeRead,
Wiki: perm.AccessModeRead,
}
}
// Permissive mode (default)
return ActionsTokenPermissions{
Contents: perm.AccessModeWrite,
Issues: perm.AccessModeWrite,
PullRequests: perm.AccessModeWrite,
Packages: perm.AccessModeRead, // Packages read by default for security
Actions: perm.AccessModeWrite,
Wiki: perm.AccessModeWrite,
}
}

// ForkPullRequestPermissions returns the restricted permissions for fork pull requests
func ForkPullRequestPermissions() ActionsTokenPermissions {
return ActionsTokenPermissions{
Contents: perm.AccessModeRead,
Issues: perm.AccessModeRead,
PullRequests: perm.AccessModeRead,
Packages: perm.AccessModeRead,
Actions: perm.AccessModeRead,
Wiki: perm.AccessModeRead,
}
}

type ActionsConfig struct {
DisabledWorkflows []string
// CollaborativeOwnerIDs is a list of owner IDs used to share actions from private repos.
// Only workflows from the private repos whose owners are in CollaborativeOwnerIDs can access the current repo's actions.
CollaborativeOwnerIDs []int64
// TokenPermissionMode defines the default permission mode (permissive or restricted)
TokenPermissionMode ActionsTokenPermissionMode `json:"token_permission_mode,omitempty"`
// DefaultTokenPermissions defines the default permissions for workflow tokens
DefaultTokenPermissions *ActionsTokenPermissions `json:"default_token_permissions,omitempty"`
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
// MaxTokenPermissions defines the maximum permissions (cannot be exceeded by workflow permissions keyword)
MaxTokenPermissions *ActionsTokenPermissions `json:"max_token_permissions,omitempty"`
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
}

func (cfg *ActionsConfig) EnableWorkflow(file string) {
Expand Down Expand Up @@ -209,6 +276,59 @@ func (cfg *ActionsConfig) IsCollaborativeOwner(ownerID int64) bool {
return slices.Contains(cfg.CollaborativeOwnerIDs, ownerID)
}

// GetTokenPermissionMode returns the token permission mode (defaults to permissive for backwards compatibility)
func (cfg *ActionsConfig) GetTokenPermissionMode() ActionsTokenPermissionMode {
if cfg.TokenPermissionMode == "" {
Comment thread
ChristopherHX marked this conversation as resolved.
Outdated
return ActionsTokenPermissionModePermissive
}
return cfg.TokenPermissionMode
}

// GetEffectiveTokenPermissions returns the effective token permissions based on settings and context
func (cfg *ActionsConfig) GetEffectiveTokenPermissions(isForkPullRequest bool) ActionsTokenPermissions {
// Fork pull requests always get restricted read-only access for security
if isForkPullRequest {
return ForkPullRequestPermissions()
}

// Use custom default permissions if set
if cfg.DefaultTokenPermissions != nil {
return *cfg.DefaultTokenPermissions
}

// Otherwise use mode-based defaults
return DefaultActionsTokenPermissions(cfg.GetTokenPermissionMode())
}

// GetMaxTokenPermissions returns the maximum allowed permissions
func (cfg *ActionsConfig) GetMaxTokenPermissions() ActionsTokenPermissions {
if cfg.MaxTokenPermissions != nil {
return *cfg.MaxTokenPermissions
}
// Default max is write for everything except packages
Comment thread
ChristopherHX marked this conversation as resolved.
Outdated
return ActionsTokenPermissions{
Contents: perm.AccessModeWrite,
Issues: perm.AccessModeWrite,
PullRequests: perm.AccessModeWrite,
Packages: perm.AccessModeWrite,
Actions: perm.AccessModeWrite,
Wiki: perm.AccessModeWrite,
}
}

// ClampPermissions ensures that the given permissions don't exceed the maximum
func (cfg *ActionsConfig) ClampPermissions(perms ActionsTokenPermissions) ActionsTokenPermissions {
maxPerms := cfg.GetMaxTokenPermissions()
return ActionsTokenPermissions{
Contents: min(perms.Contents, maxPerms.Contents),
Issues: min(perms.Issues, maxPerms.Issues),
PullRequests: min(perms.PullRequests, maxPerms.PullRequests),
Packages: min(perms.Packages, maxPerms.Packages),
Actions: min(perms.Actions, maxPerms.Actions),
Wiki: min(perms.Wiki, maxPerms.Wiki),
}
}

// FromDB fills up a ActionsConfig from serialized format.
func (cfg *ActionsConfig) FromDB(bs []byte) error {
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
Expand Down
75 changes: 75 additions & 0 deletions models/repo/repo_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package repo
import (
"testing"

"code.gitea.io/gitea/models/perm"

"github.com/stretchr/testify/assert"
)

Expand All @@ -28,3 +30,76 @@ func TestActionsConfig(t *testing.T) {
cfg.DisableWorkflow("test3.yaml")
assert.Equal(t, "test1.yaml,test2.yaml,test3.yaml", cfg.ToString())
}

func TestActionsConfigTokenPermissions(t *testing.T) {
t.Run("Default Permission Mode", func(t *testing.T) {
cfg := &ActionsConfig{}
assert.Equal(t, ActionsTokenPermissionModePermissive, cfg.GetTokenPermissionMode())
})

t.Run("Explicit Permission Mode", func(t *testing.T) {
cfg := &ActionsConfig{
TokenPermissionMode: ActionsTokenPermissionModeRestricted,
}
assert.Equal(t, ActionsTokenPermissionModeRestricted, cfg.GetTokenPermissionMode())
})

t.Run("Effective Permissions - Permissive Mode", func(t *testing.T) {
cfg := &ActionsConfig{
TokenPermissionMode: ActionsTokenPermissionModePermissive,
}
perms := cfg.GetEffectiveTokenPermissions(false)
assert.Equal(t, perm.AccessModeWrite, perms.Contents)
assert.Equal(t, perm.AccessModeWrite, perms.Issues)
assert.Equal(t, perm.AccessModeRead, perms.Packages) // Packages read by default for security
})

t.Run("Effective Permissions - Restricted Mode", func(t *testing.T) {
cfg := &ActionsConfig{
TokenPermissionMode: ActionsTokenPermissionModeRestricted,
}
perms := cfg.GetEffectiveTokenPermissions(false)
assert.Equal(t, perm.AccessModeRead, perms.Contents)
assert.Equal(t, perm.AccessModeRead, perms.Issues)
assert.Equal(t, perm.AccessModeRead, perms.Packages)
})

t.Run("Fork Pull Request Always Read-Only", func(t *testing.T) {
cfg := &ActionsConfig{
TokenPermissionMode: ActionsTokenPermissionModePermissive,
}
// Even with permissive mode, fork PRs get read-only
perms := cfg.GetEffectiveTokenPermissions(true)
assert.Equal(t, perm.AccessModeRead, perms.Contents)
assert.Equal(t, perm.AccessModeRead, perms.Issues)
assert.Equal(t, perm.AccessModeRead, perms.Packages)
})

t.Run("Clamp Permissions", func(t *testing.T) {
cfg := &ActionsConfig{
MaxTokenPermissions: &ActionsTokenPermissions{
Contents: perm.AccessModeRead,
Issues: perm.AccessModeWrite,
PullRequests: perm.AccessModeRead,
Packages: perm.AccessModeRead,
Actions: perm.AccessModeNone,
Wiki: perm.AccessModeWrite,
},
}
input := ActionsTokenPermissions{
Contents: perm.AccessModeWrite, // Should be clamped to Read
Issues: perm.AccessModeWrite, // Should stay Write
PullRequests: perm.AccessModeWrite, // Should be clamped to Read
Packages: perm.AccessModeWrite, // Should be clamped to Read
Actions: perm.AccessModeRead, // Should be clamped to None
Wiki: perm.AccessModeRead, // Should stay Read
}
clamped := cfg.ClampPermissions(input)
assert.Equal(t, perm.AccessModeRead, clamped.Contents)
assert.Equal(t, perm.AccessModeWrite, clamped.Issues)
assert.Equal(t, perm.AccessModeRead, clamped.PullRequests)
assert.Equal(t, perm.AccessModeRead, clamped.Packages)
assert.Equal(t, perm.AccessModeNone, clamped.Actions)
assert.Equal(t, perm.AccessModeRead, clamped.Wiki)
})
}
19 changes: 19 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3937,6 +3937,25 @@ general.collaborative_owner_not_exist = The collaborative owner does not exist.
general.remove_collaborative_owner = Remove Collaborative Owner
general.remove_collaborative_owner_desc = Removing a collaborative owner will prevent the repositories of the owner from accessing the actions in this repository. Continue?

general.token_permissions = Workflow Permissions
general.token_permissions.description = Configure the default permissions granted to the GITHUB_TOKEN when running workflows in this repository.
general.token_permissions.mode = Permission Mode
general.token_permissions.permissive = Read and write permissions
general.token_permissions.permissive.description = Workflows have read and write permissions in the repository for all scopes.
general.token_permissions.restricted = Read repository contents and packages permissions
general.token_permissions.restricted.description = Workflows have read permissions in the repository for the contents and packages scopes only.
general.token_permissions.fork_pr_note = Note: For workflows triggered by a pull request from a forked repository, the default GITHUB_TOKEN is always read-only.
general.token_permissions.contents = Contents
general.token_permissions.issues = Issues
general.token_permissions.pull_requests = Pull Requests
general.token_permissions.packages = Packages
general.token_permissions.actions_scope = Actions
general.token_permissions.wiki = Wiki
general.token_permissions.access_read = Read
general.token_permissions.access_write = Write
general.token_permissions.access_none = No access
general.token_permissions.update_success = Token permissions updated successfully.

[projects]
deleted.display_name = Deleted Project
type-1.display_name = Individual Project
Expand Down
40 changes: 39 additions & 1 deletion routers/web/repo/setting/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,17 @@ func ActionsGeneralSettings(ctx *context.Context) {
return
}

actionsCfg := actionsUnit.ActionsConfig()

// Token permission settings
ctx.Data["TokenPermissionMode"] = actionsCfg.GetTokenPermissionMode()
ctx.Data["TokenPermissionModePermissive"] = repo_model.ActionsTokenPermissionModePermissive
ctx.Data["TokenPermissionModeRestricted"] = repo_model.ActionsTokenPermissionModeRestricted
ctx.Data["EffectiveTokenPermissions"] = actionsCfg.GetEffectiveTokenPermissions(false)
ctx.Data["MaxTokenPermissions"] = actionsCfg.GetMaxTokenPermissions()
Comment thread
Excellencedev marked this conversation as resolved.
Outdated

if ctx.Repo.Repository.IsPrivate {
collaborativeOwnerIDs := actionsUnit.ActionsConfig().CollaborativeOwnerIDs
collaborativeOwnerIDs := actionsCfg.CollaborativeOwnerIDs
collaborativeOwners, err := user_model.GetUsersByIDs(ctx, collaborativeOwnerIDs)
if err != nil {
ctx.ServerError("GetUsersByIDs", err)
Expand Down Expand Up @@ -119,3 +128,32 @@ func DeleteCollaborativeOwner(ctx *context.Context) {

ctx.JSONOK()
}

// UpdateTokenPermissions updates the token permission settings for the repository
func UpdateTokenPermissions(ctx *context.Context) {
redirectURL := ctx.Repo.RepoLink + "/settings/actions/general"

actionsUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeActions)
if err != nil {
ctx.ServerError("GetUnit", err)
return
}

actionsCfg := actionsUnit.ActionsConfig()

// Update permission mode
permissionMode := ctx.FormString("token_permission_mode")
if permissionMode == string(repo_model.ActionsTokenPermissionModeRestricted) {
actionsCfg.TokenPermissionMode = repo_model.ActionsTokenPermissionModeRestricted
} else {
Comment thread
Excellencedev marked this conversation as resolved.
Outdated
actionsCfg.TokenPermissionMode = repo_model.ActionsTokenPermissionModePermissive
}

if err := repo_model.UpdateRepoUnit(ctx, actionsUnit); err != nil {
ctx.ServerError("UpdateRepoUnit", err)
return
}

ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
ctx.Redirect(redirectURL)
}
1 change: 1 addition & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,7 @@ func registerWebRoutes(m *web.Router) {
m.Post("/add", repo_setting.AddCollaborativeOwner)
m.Post("/delete", repo_setting.DeleteCollaborativeOwner)
})
m.Post("/token_permissions", repo_setting.UpdateTokenPermissions)
})
}, actions.MustEnableActions)
// the follow handler must be under "settings", otherwise this incomplete repo can't be accessed
Expand Down
Loading