From 2f702a9f11ca0be75a339a6a6c2ed6116e289986 Mon Sep 17 00:00:00 2001 From: Roberto Hidalgo Date: Mon, 22 May 2023 07:19:16 -0600 Subject: [PATCH] allow periodic jobs to use workload identity ACL policies (#17018) When resolving ACL policies, we were not using the parent ID for the policy lookup for dispatch/periodic jobs, even though the claims were signed for that parent ID. This prevents all calls to the Task API (and other WI-authenticated API calls) from a periodically-dispatched job failing with 403. Fix this by using the parent job ID whenever it's available. --- .changelog/17018.txt | 3 +++ nomad/acl.go | 6 +++++- nomad/variables_endpoint_test.go | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 .changelog/17018.txt diff --git a/.changelog/17018.txt b/.changelog/17018.txt new file mode 100644 index 000000000..fb60f33bd --- /dev/null +++ b/.changelog/17018.txt @@ -0,0 +1,3 @@ +```release-note:bug +identity: Fixed a bug where workload identities for periodic and dispatch jobs would not have access to their parent job's ACL policy +``` diff --git a/nomad/acl.go b/nomad/acl.go index 7cd1264db..2a26a30f4 100644 --- a/nomad/acl.go +++ b/nomad/acl.go @@ -428,7 +428,11 @@ func (s *Server) resolvePoliciesForClaims(claims *structs.IdentityClaims) ([]*st } // Find any policies attached to the job - iter, err := snap.ACLPolicyByJob(nil, alloc.Namespace, alloc.Job.ID) + jobId := alloc.Job.ID + if alloc.Job.ParentID != "" { + jobId = alloc.Job.ParentID + } + iter, err := snap.ACLPolicyByJob(nil, alloc.Namespace, jobId) if err != nil { return nil, err } diff --git a/nomad/variables_endpoint_test.go b/nomad/variables_endpoint_test.go index 14f168795..f1b1c1727 100644 --- a/nomad/variables_endpoint_test.go +++ b/nomad/variables_endpoint_test.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/nomad/acl" "github.com/hashicorp/nomad/ci" + "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" @@ -50,7 +51,8 @@ func TestVariablesEndpoint_auth(t *testing.T) { alloc3.ClientStatus = structs.AllocClientStatusRunning alloc3.Job.Namespace = ns alloc3.Namespace = ns - alloc3.Job.ParentID = jobID + parentID := uuid.Short() + alloc3.Job.ParentID = parentID alloc4 := mock.Alloc() alloc4.ClientStatus = structs.AllocClientStatusRunning @@ -224,7 +226,7 @@ func TestVariablesEndpoint_auth(t *testing.T) { name: "WI for dispatch job can read parent secret", token: idDispatchToken, cap: acl.PolicyRead, - path: fmt.Sprintf("nomad/jobs/%s", jobID), + path: fmt.Sprintf("nomad/jobs/%s", parentID), expectedErr: nil, },