Skip to content

Commit 303b2c7

Browse files
authored
Record audit entry when API tokens are auto-revoked (#2759)
Signed-off-by: Miguel Martinez <miguel@chainloop.dev>
1 parent 33407a5 commit 303b2c7

3 files changed

Lines changed: 41 additions & 4 deletions

File tree

app/controlplane/pkg/auditor/events/apitoken.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2025 The Chainloop Authors.
2+
// Copyright 2025-2026 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -95,6 +95,12 @@ type APITokenRevoked struct {
9595
*APITokenBase
9696
}
9797

98+
// RequiresActor returns false because revocations can be system-generated
99+
// (e.g. auto-revoked due to inactivity by APITokenStaleRevoker).
100+
func (a *APITokenRevoked) RequiresActor() bool {
101+
return false
102+
}
103+
98104
func (a *APITokenRevoked) ActionType() string {
99105
return APITokenRevokedActionType
100106
}

app/controlplane/pkg/auditor/events/apitoken_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2025 The Chainloop Authors.
2+
// Copyright 2025-2026 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -100,16 +100,31 @@ func TestAPITokenEvents(t *testing.T) {
100100
actor: auditor.ActorTypeAPIToken,
101101
actorID: apiTokenUUID,
102102
},
103+
{
104+
name: "API Token auto-revoked by system",
105+
event: &events.APITokenRevoked{
106+
APITokenBase: &events.APITokenBase{
107+
APITokenID: uuidPtr(apiTokenUUID),
108+
APITokenName: apiTokenName,
109+
},
110+
},
111+
expected: "testdata/apitokens/api_token_revoked_by_system.json",
112+
actor: auditor.ActorTypeSystem,
113+
actorID: uuid.Nil,
114+
},
103115
}
104116

105117
for _, tt := range tests {
106118
t.Run(tt.name, func(t *testing.T) {
107119
opts := []auditor.GeneratorOption{
108120
auditor.WithOrgID(orgUUID),
109121
}
110-
if tt.actor == auditor.ActorTypeAPIToken {
122+
switch tt.actor {
123+
case auditor.ActorTypeAPIToken:
111124
opts = append(opts, auditor.WithActor(auditor.ActorTypeAPIToken, tt.actorID, "", testAPITokenName))
112-
} else {
125+
case auditor.ActorTypeSystem:
126+
opts = append(opts, auditor.WithActor(auditor.ActorTypeSystem, uuid.Nil, "", ""))
127+
default:
113128
opts = append(opts, auditor.WithActor(auditor.ActorTypeUser, tt.actorID, testEmail, testName))
114129
}
115130

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"ActionType": "APITokenRevoked",
3+
"TargetType": "APIToken",
4+
"TargetID": "2089bb36-e27b-428b-8009-d015c8737c55",
5+
"ActorType": "SYSTEM",
6+
"ActorID": null,
7+
"ActorEmail": "",
8+
"ActorName": "",
9+
"OrgID": "1089bb36-e27b-428b-8009-d015c8737c54",
10+
"Description": "system@chainloop.dev has revoked the API token test-token",
11+
"Info": {
12+
"api_token_id": "2089bb36-e27b-428b-8009-d015c8737c55",
13+
"api_token_name": "test-token"
14+
},
15+
"Digest": "sha256:f867390a401bccbb15270dd2b54bf325dc56918925da9179af10f12787f0af24"
16+
}

0 commit comments

Comments
 (0)