Skip to content

Commit 5f709d0

Browse files
committed
support nested secrets
1 parent 21f69d0 commit 5f709d0

File tree

1 file changed

+51
-32
lines changed

1 file changed

+51
-32
lines changed

models/secret/secret.go

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,16 @@ func UpdateSecret(ctx context.Context, secretID int64, data, description string)
153153
}
154154

155155
func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[string]string, error) {
156-
secrets := map[string]string{}
156+
baseSecrets := map[string]string{}
157157

158-
secrets["GITHUB_TOKEN"] = task.Token
159-
secrets["GITEA_TOKEN"] = task.Token
158+
baseSecrets["GITHUB_TOKEN"] = task.Token
159+
baseSecrets["GITEA_TOKEN"] = task.Token
160160

161161
if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget {
162162
// ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated.
163163
// for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch
164164
// see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
165-
return secrets, nil
165+
return baseSecrets, nil
166166
}
167167

168168
ownerSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{OwnerID: task.Job.Run.Repo.OwnerID})
@@ -182,36 +182,10 @@ func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[
182182
log.Error("Unable to decrypt Actions secret %v %q, maybe SECRET_KEY is wrong: %v", secret.ID, secret.Name, err)
183183
continue
184184
}
185-
secrets[secret.Name] = v
185+
baseSecrets[secret.Name] = v
186186
}
187187

188-
if task.Job.ParentCallJobID > 0 {
189-
callerJob, err := actions_model.GetRunJobByRepoAndID(ctx, task.Job.RepoID, task.Job.ParentCallJobID)
190-
if err != nil {
191-
return nil, fmt.Errorf("GetRunJobByRepoAndID: %w", err)
192-
}
193-
if !callerJob.CallSecretsInherit {
194-
// For reusable workflow child jobs, only expose explicitly mapped secrets, plus tokens.
195-
filteredSecrets := map[string]string{}
196-
filteredSecrets["GITHUB_TOKEN"] = secrets["GITHUB_TOKEN"]
197-
filteredSecrets["GITEA_TOKEN"] = secrets["GITEA_TOKEN"]
198-
199-
if callerJob.CallSecretNames != "" {
200-
var mapping map[string]string
201-
if err := json.Unmarshal([]byte(callerJob.CallSecretNames), &mapping); err != nil {
202-
return nil, fmt.Errorf("unmarshal reusable workflow call secrets mapping for caller job %d: %w", callerJob.ID, err)
203-
}
204-
for alias, sourceName := range mapping {
205-
if v, ok := secrets[strings.ToUpper(sourceName)]; ok {
206-
filteredSecrets[alias] = v
207-
}
208-
}
209-
}
210-
secrets = filteredSecrets
211-
}
212-
}
213-
214-
return secrets, nil
188+
return getScopedSecretsForJob(ctx, task.Job, baseSecrets)
215189
}
216190

217191
func CountWrongRepoLevelSecrets(ctx context.Context) (int64, error) {
@@ -220,6 +194,51 @@ func CountWrongRepoLevelSecrets(ctx context.Context) (int64, error) {
220194
return result, err
221195
}
222196

197+
func getScopedSecretsForJob(ctx context.Context, job *actions_model.ActionRunJob, baseSecrets map[string]string) (map[string]string, error) {
198+
if job.ParentCallJobID == 0 {
199+
return baseSecrets, nil
200+
}
201+
202+
callerJob, err := actions_model.GetRunJobByRepoAndID(ctx, job.RepoID, job.ParentCallJobID)
203+
if err != nil {
204+
return nil, fmt.Errorf("GetRunJobByRepoAndID: %w", err)
205+
}
206+
207+
callerSecrets, err := getScopedSecretsForJob(ctx, callerJob, baseSecrets)
208+
if err != nil {
209+
return nil, err
210+
}
211+
if callerJob.CallSecretsInherit {
212+
return callerSecrets, nil
213+
}
214+
215+
// For reusable workflow child jobs, only expose explicitly mapped secrets, plus tokens.
216+
filteredSecrets := map[string]string{
217+
"GITHUB_TOKEN": baseSecrets["GITHUB_TOKEN"],
218+
"GITEA_TOKEN": baseSecrets["GITEA_TOKEN"],
219+
}
220+
221+
if callerJob.CallSecretNames == "" {
222+
return filteredSecrets, nil
223+
}
224+
225+
var mapping map[string]string
226+
if err := json.Unmarshal([]byte(callerJob.CallSecretNames), &mapping); err != nil {
227+
return nil, fmt.Errorf("unmarshal reusable workflow call secrets mapping for caller job %d: %w", callerJob.ID, err)
228+
}
229+
for alias, sourceName := range mapping {
230+
if v, ok := callerSecrets[sourceName]; ok {
231+
filteredSecrets[alias] = v
232+
continue
233+
}
234+
if v, ok := callerSecrets[strings.ToUpper(sourceName)]; ok {
235+
filteredSecrets[alias] = v
236+
}
237+
}
238+
239+
return filteredSecrets, nil
240+
}
241+
223242
func UpdateWrongRepoLevelSecrets(ctx context.Context) (int64, error) {
224243
result, err := db.GetEngine(ctx).Exec("UPDATE `secret` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0")
225244
if err != nil {

0 commit comments

Comments
 (0)