feat(api): scoped, optionally expiring API tokens (#6201)

* security(api): add scoped expiring API tokens

* security(api): make scoped token lifecycle enforceable

---------

Co-authored-by: n0ctal <293235942+n0ctal@users.noreply.github.com>
This commit is contained in:
n0ctal
2026-08-15 18:31:49 +05:00
committed by GitHub
parent aecbad3ab1
commit 1230559e69
19 changed files with 785 additions and 94 deletions
+12
View File
@@ -154,12 +154,24 @@ type HistoryOfSeeders struct {
// from the seconds-based API token timestamp contract.
const ApiTokenUnixMillisecondsThreshold int64 = 100_000_000_000
const (
ApiScopeAdmin = "admin"
ApiScopeMonitor = "monitor"
ApiScopeNodeSync = "node-sync"
)
func IsKnownApiScope(s string) bool {
return s == ApiScopeAdmin || s == ApiScopeMonitor || s == ApiScopeNodeSync
}
type ApiToken struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Name string `json:"name" gorm:"uniqueIndex;not null"`
Token string `json:"token" gorm:"not null"` // SHA-256 hash; the plaintext is shown only once at creation
Enabled bool `json:"enabled" gorm:"default:true"`
CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime"`
Scope string `json:"scope" gorm:"not null;default:admin"`
ExpiresAt int64 `json:"expiresAt" gorm:"not null;default:0"`
}
// MarshalJSON emits settings, streamSettings, and sniffing as nested JSON