mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
wi: new endpoint for listing workload attached ACL policies (#25588)
This introduces a new HTTP endpoint (and an associated CLI command) for querying ACL policies associated with a workload identity. It allows users that want to learn about the ACL capabilities from within WI-tasks to know what sort of policies are enabled. --------- Co-authored-by: Tim Gross <tgross@hashicorp.com> Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com>
This commit is contained in:
committed by
GitHub
parent
953910dc5d
commit
cdc308a0eb
3
.changelog/25588.txt
Normal file
3
.changelog/25588.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
wi: new API endpoint for listing workload-attached ACL policies
|
||||
```
|
||||
11
api/acl.go
11
api/acl.go
@@ -67,6 +67,16 @@ func (a *ACLPolicies) Info(policyName string, q *QueryOptions) (*ACLPolicy, *Que
|
||||
return &resp, wm, nil
|
||||
}
|
||||
|
||||
// Self is used to query policies attached to a workload identity
|
||||
func (a *ACLPolicies) Self(q *QueryOptions) ([]*ACLPolicyListStub, *QueryMeta, error) {
|
||||
var resp []*ACLPolicyListStub
|
||||
wm, err := a.client.query("/v1/acl/policy/self", &resp, q)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return resp, wm, nil
|
||||
}
|
||||
|
||||
// ACLTokens is used to query the ACL token endpoints.
|
||||
type ACLTokens struct {
|
||||
client *Client
|
||||
@@ -509,6 +519,7 @@ func (a *ACLAuth) Login(req *ACLLoginRequest, q *WriteOptions) (*ACLToken, *Writ
|
||||
type ACLPolicyListStub struct {
|
||||
Name string
|
||||
Description string
|
||||
JobACL *JobACL
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
129
command/acl_policy_self.go
Normal file
129
command/acl_policy_self.go
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
type ACLPolicySelfCommand struct {
|
||||
Meta
|
||||
|
||||
json bool
|
||||
tmpl string
|
||||
}
|
||||
|
||||
func (c *ACLPolicySelfCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad acl policy self
|
||||
|
||||
Self is used to fetch information about the policy assigned to the current
|
||||
workload identity or ACL token.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) + `
|
||||
|
||||
ACL List Options:
|
||||
|
||||
-json
|
||||
Output the ACL policies in a JSON format.
|
||||
|
||||
-t
|
||||
Format and display the ACL policies using a Go template.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *ACLPolicySelfCommand) AutocompleteFlags() complete.Flags {
|
||||
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
|
||||
complete.Flags{
|
||||
"-json": complete.PredictNothing,
|
||||
"-t": complete.PredictAnything,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ACLPolicySelfCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictNothing
|
||||
}
|
||||
|
||||
func (c *ACLPolicySelfCommand) Synopsis() string {
|
||||
return "Lookup self ACL policy assigned to the workload identity or ACL token"
|
||||
}
|
||||
|
||||
func (c *ACLPolicySelfCommand) Name() string { return "acl policy self" }
|
||||
|
||||
func (c *ACLPolicySelfCommand) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&c.json, "json", false, "")
|
||||
flags.StringVar(&c.tmpl, "t", "", "")
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Check that we have no arguments
|
||||
args = flags.Args()
|
||||
if l := len(args); l != 0 {
|
||||
c.Ui.Error("This command takes no arguments")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Get the HTTP client
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
policies, _, err := client.ACLPolicies().Self(nil)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error fetching WI policies: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(policies) == 0 {
|
||||
c.Ui.Output("No policies found.")
|
||||
} else {
|
||||
if c.json || len(c.tmpl) > 0 {
|
||||
out, err := Format(c.json, c.tmpl, policies)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output(out)
|
||||
return 0
|
||||
}
|
||||
|
||||
output := make([]string, 0, len(policies)+1)
|
||||
output = append(output, "Name|Job ID|Group Name|Task Name")
|
||||
for _, p := range policies {
|
||||
var outputString string
|
||||
if p.JobACL == nil {
|
||||
outputString = fmt.Sprintf("%s|%s|%s|%s", p.Name, "<unavailable>", "<unavailable>", "<unavailable>")
|
||||
} else {
|
||||
outputString = fmt.Sprintf(
|
||||
"%s|%s|%s|%s",
|
||||
p.Name, formatJobACL(p.JobACL.JobID), formatJobACL(p.JobACL.Group), formatJobACL(p.JobACL.Task),
|
||||
)
|
||||
}
|
||||
output = append(output, outputString)
|
||||
}
|
||||
|
||||
c.Ui.Output(formatList(output))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func formatJobACL(jobACL string) string {
|
||||
if jobACL == "" {
|
||||
return "<not specified>"
|
||||
}
|
||||
return jobACL
|
||||
}
|
||||
79
command/acl_policy_self_test.go
Normal file
79
command/acl_policy_self_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/cli"
|
||||
"github.com/hashicorp/nomad/command/agent"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
"github.com/shoenig/test/must"
|
||||
)
|
||||
|
||||
func TestACLPolicySelfCommand_ViaEnvVar(t *testing.T) {
|
||||
config := func(c *agent.Config) {
|
||||
c.ACL.Enabled = true
|
||||
}
|
||||
|
||||
srv, _, url := testServer(t, true, config)
|
||||
defer srv.Shutdown()
|
||||
|
||||
state := srv.Agent.Server().State()
|
||||
|
||||
// Bootstrap an initial ACL token
|
||||
token := srv.RootToken
|
||||
must.NotNil(t, token)
|
||||
|
||||
// Create a minimal job
|
||||
job := mock.MinJob()
|
||||
|
||||
// Add a job policy
|
||||
polArgs := structs.ACLPolicyUpsertRequest{
|
||||
Policies: []*structs.ACLPolicy{
|
||||
{
|
||||
Name: "nw",
|
||||
Description: "test job can write to nodes",
|
||||
Rules: `node { policy = "write" }`,
|
||||
JobACL: &structs.JobACL{
|
||||
Namespace: job.Namespace,
|
||||
JobID: job.ID,
|
||||
},
|
||||
},
|
||||
},
|
||||
WriteRequest: structs.WriteRequest{
|
||||
Region: job.Region,
|
||||
AuthToken: token.SecretID,
|
||||
Namespace: job.Namespace,
|
||||
},
|
||||
}
|
||||
polReply := structs.GenericResponse{}
|
||||
must.NoError(t, srv.RPC("ACL.UpsertPolicies", &polArgs, &polReply))
|
||||
must.NonZero(t, polReply.WriteMeta.Index)
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
cmd := &ACLPolicySelfCommand{Meta: Meta{Ui: ui, flagAddress: url}}
|
||||
|
||||
allocs := testutil.WaitForRunningWithToken(t, srv.RPC, job, token.SecretID)
|
||||
must.Len(t, 1, allocs)
|
||||
|
||||
alloc, err := state.AllocByID(nil, allocs[0].ID)
|
||||
must.NoError(t, err)
|
||||
must.MapContainsKey(t, alloc.SignedIdentities, "t")
|
||||
wid := alloc.SignedIdentities["t"]
|
||||
|
||||
// Fetch info on policies with a JWT
|
||||
t.Setenv("NOMAD_TOKEN", wid)
|
||||
code := cmd.Run([]string{"-address=" + url})
|
||||
must.Zero(t, code)
|
||||
|
||||
// Check the output
|
||||
out := ui.OutputWriter.String()
|
||||
must.StrContains(t, out, polArgs.Policies[0].Name)
|
||||
|
||||
// make sure we put the job ACLs in there, too
|
||||
must.StrContains(t, out, polArgs.Policies[0].JobACL.JobID)
|
||||
}
|
||||
@@ -5,8 +5,10 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
@@ -63,14 +65,30 @@ func (c *ACLTokenSelfCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Get the specified token information
|
||||
// Check what kind of token we have available
|
||||
envToken := os.Getenv("NOMAD_TOKEN")
|
||||
if envToken == "" {
|
||||
c.Ui.Error("No token present in the environment")
|
||||
return 1
|
||||
}
|
||||
|
||||
// Does this look like a Nomad ACL token?
|
||||
if helper.IsUUID(envToken) {
|
||||
token, _, err := client.ACLTokens().Self(nil)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error fetching self token: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Format the output
|
||||
outputACLToken(c.Ui, token)
|
||||
return 0
|
||||
}
|
||||
|
||||
policies, _, err := client.ACLPolicies().Self(nil)
|
||||
if err == nil && len(policies) > 0 {
|
||||
c.Ui.Info("No ACL token found but there are ACL policies attached to this workload identity. You can query them with acl policy self command.")
|
||||
return 0
|
||||
}
|
||||
c.Ui.Error("No ACL tokens, nor ACL policies attached to a workload identity found.")
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
@@ -34,6 +35,11 @@ func (s *HTTPServer) ACLPoliciesRequest(resp http.ResponseWriter, req *http.Requ
|
||||
}
|
||||
|
||||
func (s *HTTPServer) ACLPolicySpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
// handle the special case for "self" call
|
||||
if req.URL.Path == "/v1/acl/policy/self" {
|
||||
return s.aclSelfPolicy(resp, req)
|
||||
}
|
||||
|
||||
name := strings.TrimPrefix(req.URL.Path, "/v1/acl/policy/")
|
||||
if len(name) == 0 {
|
||||
return nil, CodedError(400, "Missing Policy Name")
|
||||
@@ -46,7 +52,7 @@ func (s *HTTPServer) ACLPolicySpecificRequest(resp http.ResponseWriter, req *htt
|
||||
case http.MethodDelete:
|
||||
return s.aclPolicyDelete(resp, req, name)
|
||||
default:
|
||||
return nil, CodedError(405, ErrInvalidMethod)
|
||||
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +186,51 @@ func (s *HTTPServer) ACLTokenSpecificRequest(resp http.ResponseWriter, req *http
|
||||
return s.aclTokenCrud(resp, req, accessor)
|
||||
}
|
||||
|
||||
func (s *HTTPServer) aclSelfPolicy(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
if req.Method != http.MethodGet {
|
||||
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
||||
}
|
||||
|
||||
wiPolicyReq := structs.GenericRequest{}
|
||||
if s.parse(resp, req, &wiPolicyReq.Region, &wiPolicyReq.QueryOptions) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// is it a JWT or a Nomad ACL token?
|
||||
if !helper.IsUUID(wiPolicyReq.AuthToken) {
|
||||
|
||||
// Resolve policies for workload identities
|
||||
wiPolicyReply := structs.ACLPolicySetResponse{}
|
||||
if err := s.agent.RPC("ACL.GetClaimPolicies", &wiPolicyReq, &wiPolicyReply); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wiPolicyReply.Policies == nil {
|
||||
wiPolicyReply.Policies = make(map[string]*structs.ACLPolicy, 0)
|
||||
}
|
||||
|
||||
// convert the output into ACLPolicyListResponse to get consistent API
|
||||
// output
|
||||
reply := structs.ACLPolicyListResponse{}
|
||||
for _, wiReply := range wiPolicyReply.Policies {
|
||||
reply.Policies = append(reply.Policies, wiReply.Stub())
|
||||
}
|
||||
|
||||
setMeta(resp, &reply.QueryMeta)
|
||||
return reply.Policies, nil
|
||||
}
|
||||
|
||||
// Resolve any authenticated policies
|
||||
policiesListReq := &structs.ACLPolicyListRequest{QueryOptions: wiPolicyReq.QueryOptions}
|
||||
policiesListReply := structs.ACLPolicyListResponse{}
|
||||
if err := s.agent.RPC("ACL.ListPolicies", policiesListReq, &policiesListReply); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setMeta(resp, &policiesListReply.QueryMeta)
|
||||
return policiesListReply.Policies, nil
|
||||
}
|
||||
|
||||
func (s *HTTPServer) aclTokenCrud(resp http.ResponseWriter, req *http.Request,
|
||||
tokenAccessor string) (interface{}, error) {
|
||||
if tokenAccessor == "" {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/hashicorp/nomad/helper/uuid"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
"github.com/shoenig/test/must"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -123,6 +124,69 @@ func TestHTTP_ACLPolicyQuery(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHTTP_ACLPolicySelfQuery(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
job := mock.MinJob()
|
||||
p1 := &structs.ACLPolicy{
|
||||
Name: "nw",
|
||||
Description: "test job can write to nodes",
|
||||
Rules: `node { policy = "write" }`,
|
||||
JobACL: &structs.JobACL{
|
||||
Namespace: job.Namespace,
|
||||
JobID: job.ID,
|
||||
},
|
||||
}
|
||||
p2 := mock.ACLPolicy()
|
||||
p3 := mock.ACLPolicy()
|
||||
args := structs.ACLPolicyUpsertRequest{
|
||||
Policies: []*structs.ACLPolicy{p1, p2, p3},
|
||||
WriteRequest: structs.WriteRequest{
|
||||
Region: "global",
|
||||
AuthToken: s.RootToken.SecretID,
|
||||
},
|
||||
}
|
||||
var resp structs.GenericResponse
|
||||
must.NoError(t, s.Agent.RPC("ACL.UpsertPolicies", &args, &resp))
|
||||
|
||||
// get the WI JWT from state
|
||||
allocs := testutil.WaitForRunningWithToken(t, s.RPC, job, s.RootToken.SecretID)
|
||||
must.Len(t, 1, allocs)
|
||||
|
||||
state := s.Agent.server.State()
|
||||
|
||||
alloc, err := state.AllocByID(nil, allocs[0].ID)
|
||||
must.NoError(t, err)
|
||||
must.MapContainsKey(t, alloc.SignedIdentities, "t")
|
||||
wid := alloc.SignedIdentities["t"]
|
||||
|
||||
// Make the HTTP request
|
||||
req, err := http.NewRequest(http.MethodGet, "/v1/acl/policy/self", nil)
|
||||
must.NoError(t, err)
|
||||
|
||||
respW := httptest.NewRecorder()
|
||||
req.Header.Set("X-Nomad-Token", wid)
|
||||
|
||||
// Make the request
|
||||
obj, err := s.Server.aclSelfPolicy(respW, req)
|
||||
must.NoError(t, err)
|
||||
|
||||
// Check the output
|
||||
n := obj.([]*structs.ACLPolicyListStub)
|
||||
must.Eq(t, n[0].JobACL, p1.JobACL)
|
||||
must.SliceLen(t, 1, n) // only 1 policy is assigned to the WID
|
||||
|
||||
// Make the without JWT
|
||||
req.Header.Set("X-Nomad-Token", s.RootToken.SecretID)
|
||||
obj, err = s.Server.aclSelfPolicy(respW, req)
|
||||
must.NoError(t, err)
|
||||
|
||||
// We should get all the policies now
|
||||
nn := obj.([]*structs.ACLPolicyListStub)
|
||||
must.SliceLen(t, 3, nn)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHTTP_ACLPolicyCreate(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
|
||||
@@ -173,6 +173,11 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"acl policy self": func() (cli.Command, error) {
|
||||
return &ACLPolicySelfCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"acl role": func() (cli.Command, error) {
|
||||
return &ACLRoleCommand{
|
||||
Meta: meta,
|
||||
|
||||
@@ -13242,6 +13242,7 @@ func (a *ACLPolicy) Stub() *ACLPolicyListStub {
|
||||
return &ACLPolicyListStub{
|
||||
Name: a.Name,
|
||||
Description: a.Description,
|
||||
JobACL: a.JobACL,
|
||||
Hash: a.Hash,
|
||||
CreateIndex: a.CreateIndex,
|
||||
ModifyIndex: a.ModifyIndex,
|
||||
@@ -13284,6 +13285,7 @@ func (a *ACLPolicy) Validate() error {
|
||||
type ACLPolicyListStub struct {
|
||||
Name string
|
||||
Description string
|
||||
JobACL *JobACL
|
||||
Hash []byte
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
|
||||
@@ -155,6 +155,50 @@ $ curl \
|
||||
}
|
||||
```
|
||||
|
||||
## Read Self Policy
|
||||
|
||||
This endpoint reads the ACL policies associated with the current workload
|
||||
identity or any authenticated request.
|
||||
|
||||
| Method | Path | Produces |
|
||||
|--------|-----------------------|--------------------|
|
||||
| `GET` | `/v1/acl/policy/self` | `application/json` |
|
||||
|
||||
This table shows this endpoint's support for
|
||||
[blocking queries](/nomad/api-docs#blocking-queries), [consistency modes](/nomad/api-docs#consistency-modes) and
|
||||
[required ACLs](/nomad/api-docs#acls).
|
||||
|
||||
| Blocking Queries | Consistency Modes | ACL Required |
|
||||
|------------------|-------------------|---------------------------------|
|
||||
| `YES` | `all` | Any valid Workload Identity JWT |
|
||||
|
||||
### Sample Request
|
||||
|
||||
```shell-session
|
||||
$ curl --header "X-Nomad-Token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImJiMmUwYjI5LTIyZTYtYjk0My0yN2M1LThkYmNmMjc5ODM0MCIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJub21hZHByb2plY3QuaW8iLCJpYXQiOjE3NDM2OTI5NzksImp0aSI6IjJmOWI3ZGRmLWU1M2ItZGMxNS1kMzU4LTAyMDk5NjE1NThlMyIsIm5iZiI6MTc0MzY5Mjk3OSwibm9tYWRfYWxsb2NhdGlvbl9pZCI6IjhjMGJjMWFjLWRlMzMtYTNlYi03YWUwLTZiZjM3OGY5YzcxYiIsIm5vbWFkX2pvYl9pZCI6Im5vbWFkIiwibm9tYWRfbmFtZXNwYWNlIjoiZGVmYXVsdCIsIm5vbWFkX3Rhc2siOiJzZXJ2ZXIiLCJzdWIiOiJnbG9iYWw6ZGVmYXVsdDpub21hZDpub21hZDpzZXJ2ZXI6ZGVmYXVsdCJ9.IDZWTqGWRURDwI5OvO3LLjCsU1qzg6LEG4q5S7CfZawUXzMqAOoYajI_nynOGJp2aU77MqUyJmdFtrIBMoQnIxclEwNl9DkhfOrgjBsWefn9JqKEpORGD-0OLzaoYUgbu0k6aXCNktfpvHZN5uUsfL6nLOG-osQvHn9ZdboT31tjp1v6d-MfP96ZLG0NrXgLWMfwan2AAzuqMabIS9iO6OrZDNp2-TeeY_sqM-7sNEgfDo33GAeyhqTi8CAZhsDOv4wtJuFfMhrsbb33wHdAiltjXlafBtncMMaLHr07gbLvOMfty2_193i4Yi3H2PgPr7c4BYHoXyQJhFchDyYmFA" \
|
||||
https://localhost:4646/v1/acl/policy/self
|
||||
```
|
||||
|
||||
### Sample Response
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"CreateIndex": 22,
|
||||
"Description": "",
|
||||
"Hash": "SmmKR0rW0WA0Bfpk7m3D8wqgrL0dtkY3DwAucF9YN4Y=",
|
||||
"JobACL": {
|
||||
"Group": "nomad",
|
||||
"JobID": "nomad",
|
||||
"Namespace": "default",
|
||||
"Task": ""
|
||||
},
|
||||
"ModifyIndex": 22,
|
||||
"Name": "nomad-policy"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Delete Policy
|
||||
|
||||
This endpoint deletes the named ACL policy. This request is always forwarded to the
|
||||
|
||||
@@ -37,6 +37,7 @@ subcommands are available:
|
||||
- [`acl policy delete`][policydelete] - Delete an existing ACL policies
|
||||
- [`acl policy info`][policyinfo] - Fetch information on an existing ACL policy
|
||||
- [`acl policy list`][policylist] - List available ACL policies
|
||||
- [`acl policy self`][policyself] - List ACL policies attached to the current workload
|
||||
- [`acl role create`][rolecreate] - Create a new ACL role
|
||||
- [`acl role delete`][roledelete] - Delete an existing ACL role
|
||||
- [`acl role info`][roleinfo] - Get info on an existing ACL role
|
||||
@@ -64,6 +65,7 @@ subcommands are available:
|
||||
[policydelete]: /nomad/docs/commands/acl/policy/delete
|
||||
[policyinfo]: /nomad/docs/commands/acl/policy/info
|
||||
[policylist]: /nomad/docs/commands/acl/policy/list
|
||||
[policyself]: /nomad/docs/commands/acl/policy/self
|
||||
[tokencreate]: /nomad/docs/commands/acl/token/create
|
||||
[tokenupdate]: /nomad/docs/commands/acl/token/update
|
||||
[tokendelete]: /nomad/docs/commands/acl/token/delete
|
||||
|
||||
54
website/content/docs/commands/acl/policy/self.mdx
Normal file
54
website/content/docs/commands/acl/policy/self.mdx
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: 'nomad acl policy self command reference'
|
||||
description: >
|
||||
The `nomad acl policy self` command fetches information about the currently set access control list (ACL) policies available to the authenticated request.
|
||||
---
|
||||
|
||||
# `nomad acl policy self` command reference
|
||||
|
||||
The `nomad acl policy self` command fetches information about the currently
|
||||
set ACL policies attached to the workload or ACL tokens.
|
||||
|
||||
## Usage
|
||||
|
||||
```plaintext
|
||||
nomad acl policy self [options]
|
||||
```
|
||||
|
||||
## General options
|
||||
|
||||
@include 'general_options_no_namespace.mdx'
|
||||
|
||||
## Self options
|
||||
|
||||
- `-json` : Output the ACL policies in a JSON format.
|
||||
|
||||
- `-t` : Format and display the ACL policies using a Go template.
|
||||
|
||||
## Examples
|
||||
|
||||
Fetch information about an existing ACL policies attached to the workload.
|
||||
|
||||
```shell-session
|
||||
$ echo $NOMAD_TOKEN
|
||||
eyJhbGciOiJSUzI1NiIsImtpZCI6ImJiMmUwYjI5LTIyZTYtYjk0My0yN2M1LThkYmNmMjc5ODM0MCIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJub21hZHByb2plY3QuaW8iLCJpYXQiOjE3NDM2OTI5NzksImp0aSI6IjJmOWI3ZGRmLWU1M2ItZGMxNS1kMzU4LTAyMDk5NjE1NThlMyIsIm5iZiI6MTc0MzY5Mjk3OSwibm9tYWRfYWxsb2NhdGlvbl9pZCI6IjhjMGJjMWFjLWRlMzMtYTNlYi03YWUwLTZiZjM3OGY5YzcxYiIsIm5vbWFkX2pvYl9pZCI6Im5vbWFkIiwibm9tYWRfbmFtZXNwYWNlIjoiZGVmYXVsdCIsIm5vbWFkX3Rhc2siOiJzZXJ2ZXIiLCJzdWIiOiJnbG9iYWw6ZGVmYXVsdDpub21hZDpub21hZDpzZXJ2ZXI6ZGVmYXVsdCJ9.IDZWTqGWRURDwI5OvO3LLjCsU1qzg6LEG4q5S7CfZawUXzMqAOoYajI_nynOGJp2aU77MqUyJmdFtrIBMoQnIxclEwNl9DkhfOrgjBsWefn9JqKEpORGD-0OLzaoYUgbu0k6aXCNktfpvHZN5uUsfL6nLOG-osQvHn9ZdboT31tjp1v6d-MfP96ZLG0NrXgLWMfwan2AAzuqMabIS9iO6OrZDNp2-TeeY_sqM-7sNEgfDo33GAeyhqTi8CAZhsDOv4wtJuFfMhrsbb33wHdAiltjXlafBtncMMaLHr07gbLvOMfty2_193i4Yi3H2PgPr7c4BYHoXyQJhFchDyYmFA
|
||||
$ nomad acl policy self
|
||||
Name Job ID Group Name Task Name
|
||||
nomad-policy nomad nomad <not specified>
|
||||
$ nomad acl policy self -json
|
||||
[
|
||||
{
|
||||
"CreateIndex": 22,
|
||||
"Description": "",
|
||||
"JobACL": {
|
||||
"Group": "nomad",
|
||||
"JobID": "nomad",
|
||||
"Namespace": "default",
|
||||
"Task": ""
|
||||
},
|
||||
"ModifyIndex": 22,
|
||||
"Name": "nomad-policy"
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -40,3 +40,13 @@ Modify Index = 8
|
||||
Policies = n/a
|
||||
Roles = n/a
|
||||
```
|
||||
|
||||
The command also detects if the current Nomad token is a workload identity
|
||||
JWT and respond with a hint if that's the case.
|
||||
|
||||
```shell-session
|
||||
$ echo $NOMAD_TOKEN
|
||||
eyJhbGciOiJSUzI1NiIsImtpZCI6ImJiMmUwYjI5LTIyZTYtYjk0My0yN2M1LThkYmNmMjc5ODM0MCIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJub21hZHByb2plY3QuaW8iLCJpYXQiOjE3NDM2OTI5NzksImp0aSI6IjJmOWI3ZGRmLWU1M2ItZGMxNS1kMzU4LTAyMDk5NjE1NThlMyIsIm5iZiI6MTc0MzY5Mjk3OSwibm9tYWRfYWxsb2NhdGlvbl9pZCI6IjhjMGJjMWFjLWRlMzMtYTNlYi03YWUwLTZiZjM3OGY5YzcxYiIsIm5vbWFkX2pvYl9pZCI6Im5vbWFkIiwibm9tYWRfbmFtZXNwYWNlIjoiZGVmYXVsdCIsIm5vbWFkX3Rhc2siOiJzZXJ2ZXIiLCJzdWIiOiJnbG9iYWw6ZGVmYXVsdDpub21hZDpub21hZDpzZXJ2ZXI6ZGVmYXVsdCJ9.IDZWTqGWRURDwI5OvO3LLjCsU1qzg6LEG4q5S7CfZawUXzMqAOoYajI_nynOGJp2aU77MqUyJmdFtrIBMoQnIxclEwNl9DkhfOrgjBsWefn9JqKEpORGD-0OLzaoYUgbu0k6aXCNktfpvHZN5uUsfL6nLOG-osQvHn9ZdboT31tjp1v6d-MfP96ZLG0NrXgLWMfwan2AAzuqMabIS9iO6OrZDNp2-TeeY_sqM-7sNEgfDo33GAeyhqTi8CAZhsDOv4wtJuFfMhrsbb33wHdAiltjXlafBtncMMaLHr07gbLvOMfty2_193i4Yi3H2PgPr7c4BYHoXyQJhFchDyYmFA
|
||||
$ nomad acl token self
|
||||
No ACL token found but there are ACL policies attached to this workload identity. You can query them with acl policy self command.
|
||||
```
|
||||
@@ -453,6 +453,10 @@
|
||||
{
|
||||
"title": "list",
|
||||
"path": "commands/acl/policy/list"
|
||||
},
|
||||
{
|
||||
"title": "self",
|
||||
"path": "commands/acl/policy/self"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user