identity: prevent missing task identity from panicking server (#23763)

Tasks have a default identity created during canonicalization. If this default
identity is somehow missing, we'll hit panics when trying to create and sign the
claims in the plan applier. Fallback to the default identity if it's missing
from the task.

This changeset will need a different implementation in 1.7.x+ent backports, as
the constructor for identities was refactored significantly in #23708. The panic
cannot occur in 1.6.x+ent.

Fixes: https://github.com/hashicorp/nomad/issues/23758
This commit is contained in:
Tim Gross
2024-08-07 15:26:20 -04:00
committed by GitHub
parent d131c41943
commit bcb0ee3031
4 changed files with 26 additions and 2 deletions

3
.changelog/23763.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
identity: Fixed a bug where a missing default task identity could panic the leader
```

View File

@@ -242,6 +242,10 @@ const keyIDHeader = "kid"
// SignClaims adds the Issuer claim prior to signing.
func (e *Encrypter) SignClaims(claims *structs.IdentityClaims) (string, string, error) {
if claims == nil {
return "", "", errors.New("cannot sign empty claims")
}
// If a key is rotated immediately following a leader election, plans that
// are in-flight may get signed before the new leader has the key. Allow for
// a short timeout-and-retry to avoid rejecting plans

View File

@@ -8055,9 +8055,10 @@ func (t *Task) Canonicalize(job *Job, tg *TaskGroup) {
// If there was no default identity, always create one.
if t.Identity == nil {
t.Identity = &WorkloadIdentity{}
t.Identity = DefaultWorkloadIdentity()
} else {
t.Identity.Canonicalize()
}
t.Identity.Canonicalize()
}
func (t *Task) GoString() string {

View File

@@ -110,6 +110,9 @@ func NewIdentityClaimsBuilder(job *Job, alloc *Allocation, wihandle *WIHandle, w
if tg == nil {
return nil
}
if wid == nil {
wid = DefaultWorkloadIdentity()
}
return &IdentityClaimsBuilder{
alloc: alloc,
@@ -318,9 +321,19 @@ type WorkloadIdentity struct {
// escalate their privileges if they know what claim mappings to expect.
}
func DefaultWorkloadIdentity() *WorkloadIdentity {
return &WorkloadIdentity{
Name: WorkloadIdentityDefaultName,
Audience: []string{WorkloadIdentityDefaultAud},
}
}
// IsConsul returns true if the identity name starts with the standard prefix
// for Consul tasks and services.
func (wi *WorkloadIdentity) IsConsul() bool {
if wi == nil {
return false
}
return strings.HasPrefix(wi.Name, ConsulTaskIdentityNamePrefix) ||
strings.HasPrefix(wi.Name, ConsulServiceIdentityNamePrefix)
}
@@ -328,6 +341,9 @@ func (wi *WorkloadIdentity) IsConsul() bool {
// IsVault returns true if the identity name starts with the standard prefix
// for Vault tasks.
func (wi *WorkloadIdentity) IsVault() bool {
if wi == nil {
return false
}
return strings.HasPrefix(wi.Name, WorkloadIdentityVaultPrefix)
}