Add ac claim for old docker/build-push-action@v3 / current buildx gha cache (#29584)

Also resolves a warning for current releases

```
| ##[group]GitHub Actions runtime token ACs
| ##[warning]Cannot parse GitHub Actions Runtime Token ACs: "undefined" is not valid JSON
| ##[endgroup]
====>
| ##[group]GitHub Actions runtime token ACs
| ##[endgroup]
```
\* this is an error in v3

References in the docker org:
-
831ca179d3/src/main.ts (L24)
-
7d8b4dc669/src/github.ts (L61)

No known official action of GitHub makes use of this claim.

Current releases throw an error when configure to use actions cache
```
| ERROR: failed to solve: failed to configure gha cache exporter: invalid token without access controls
| ##[error]buildx failed with: ERROR: failed to solve: failed to configure gha cache exporter: invalid token without access controls
```

(cherry picked from commit 368743baf3d904f86b553a88718583906f571c87)
This commit is contained in:
ChristopherHX 2024-03-05 18:34:42 +01:00 committed by Earl Warren
parent e7afba21ce
commit b058fb4012
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 0579CB2928A78A00
2 changed files with 34 additions and 0 deletions

View file

@ -9,6 +9,7 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -21,17 +22,41 @@ type actionsClaims struct {
TaskID int64 TaskID int64
RunID int64 RunID int64
JobID int64 JobID int64
Ac string `json:"ac"`
} }
type actionsCacheScope struct {
Scope string
Permission actionsCachePermission
}
type actionsCachePermission int
const (
actionsCachePermissionRead = 1 << iota
actionsCachePermissionWrite
)
func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) { func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) {
now := time.Now() now := time.Now()
ac, err := json.Marshal(&[]actionsCacheScope{
{
Scope: "",
Permission: actionsCachePermissionWrite,
},
})
if err != nil {
return "", err
}
claims := actionsClaims{ claims := actionsClaims{
RegisteredClaims: jwt.RegisteredClaims{ RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)), ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)),
NotBefore: jwt.NewNumericDate(now), NotBefore: jwt.NewNumericDate(now),
}, },
Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID), Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID),
Ac: string(ac),
TaskID: taskID, TaskID: taskID,
RunID: runID, RunID: runID,
JobID: jobID, JobID: jobID,

View file

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"testing" "testing"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
@ -29,6 +30,14 @@ func TestCreateAuthorizationToken(t *testing.T) {
taskIDClaim, ok := claims["TaskID"] taskIDClaim, ok := claims["TaskID"]
assert.True(t, ok, "Has TaskID claim in jwt token") assert.True(t, ok, "Has TaskID claim in jwt token")
assert.Equal(t, float64(taskID), taskIDClaim, "Supplied taskid must match stored one") assert.Equal(t, float64(taskID), taskIDClaim, "Supplied taskid must match stored one")
acClaim, ok := claims["ac"]
assert.True(t, ok, "Has ac claim in jwt token")
ac, ok := acClaim.(string)
assert.True(t, ok, "ac claim is a string for buildx gha cache")
scopes := []actionsCacheScope{}
err = json.Unmarshal([]byte(ac), &scopes)
assert.NoError(t, err, "ac claim is a json list for buildx gha cache")
assert.GreaterOrEqual(t, len(scopes), 1, "Expected at least one action cache scope for buildx gha cache")
} }
func TestParseAuthorizationToken(t *testing.T) { func TestParseAuthorizationToken(t *testing.T) {