PageSourceSearch

https://mpolinowski.github.io/assets/js/737d225d.daf2c793.js

js mpolinowski.github.io collected 2026-10-03 09:39:10 UTC 25,752 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkmikes_dev_notebook=globalThis.webpackChunkmikes_dev_notebook||[]).push([[5651],{98213(e,n,o){o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>t,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control/index","title":"Hashicorp Nomad Access Control","description":"Shen Zhen, China","source":"@site/docs/DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control/index.md","sourceDirName":"DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control","slug":"/DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control/2022-05-19","permalink":"/docs/DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control/2022-05-19","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/DevOps/Hashicorp/2022-05-19-hashicorp-dojo-nomad-access-control/index.md","tags":[{"inline":true,"label":"Nomad","permalink":"/docs/tags/nomad"},{"inline":true,"label":"LINUX","permalink":"/docs/tags/linux"}],"version":"current","sidebarPosition":6000,"frontMatter":{"sidebar_position":6000,"slug":"2022-05-19","title":"Hashicorp Nomad Access Control","authors":"mpolinowski","tags":["Nomad","LINUX"]},"sidebar":"tutorialSidebar","previous":{"title":"Hashicorp Nomad with Consul Service Discovery","permalink":"/docs/DevOps/Hashicorp/2022-05-20-hashicorp-dojo-nomad-consul/2022-05-20"},"next":{"title":"Hashicorp Nomad Adding Encryption to your Cluster","permalink":"/docs/DevOps/Hashicorp/2022-05-18-hashicorp-dojo-nomad-adding-encryption/2022-05-18"}}');var i=o(474848),a=o(28453);const l={sidebar_position:6e3,slug:"2022-05-19",title:"Hashicorp Nomad Access Control",authors:"mpolinowski",tags:["Nomad","LINUX"]},t=void 0,r={},c=[{value:"Nomad ACL System",id:"nomad-acl-system",level:2},{value:"Core objects",id:"core-objects",level:3},{value:"Enable ACLs on Nomad servers",id:"enable-acls-on-nomad-servers",level:2},{value:"Stage a Permissive Anonymous Policy",id:"stage-a-permissive-anonymous-policy",level:3},{value:"Run the Bootstrap Command",id:"run-the-bootstrap-command",level:3},{value:"Using the Management Token",id:"using-the-management-token",level:4},{value:"Deploy your anonymous policy",id:"deploy-your-anonymous-policy",level:3},{value:"Create Management Tokens for Other Regions",id:"create-management-tokens-for-other-regions",level:3},{value:"Generate a Client Token",id:"generate-a-client-token",level:3},{value:"Nomad ACL Policies",id:"nomad-acl-policies",level:2},{value:"Agent rules",id:"agent-rules",level:3},{value:"Operator rules",id:"operator-rules",level:3},{value:"Quota rules",id:"quota-rules",level:3},{value:"Host Volume rules",id:"host-volume-rules",level:3},{value:"Plugin rules",id:"plugin-rules",level:3},{value:"Generate User Token",id:"generate-user-token",level:2},{value:"Application Developer",id:"application-developer",level:3},{value:"Production Operations",id:"production-operations",level:3},{value:"Generate Nomad Tokens with HashiCorp Vault (WIP)",id:"generate-nomad-tokens-with-hashicorp-vault-wip",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Shen Zhen, China",src:o(963697).A+"",width:"2230",height:"839"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#nomad-acl-system",children:"Nomad ACL System"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#core-objects",children:"Core objects"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#enable-acls-on-nomad-servers",children:"Enable ACLs on Nomad servers"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#stage-a-permissive-anonymous-policy",children:"Stage a Permissive Anonymous Policy"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#run-the-bootstrap-command",children:"Run the Bootstrap Command"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-the-management-token",children:"Using the Management Token"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#deploy-your-anonymous-policy",children:"Deploy your anonymous policy"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#create-management-tokens-for-other-regions",children:"Create Management Tokens for Other Regions"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#generate-a-client-token",children:"Generate a Client Token"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#nomad-acl-policies",children:"Nomad ACL Policies"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#agent-rules",children:"Agent rules"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#operator-rules",children:"Operator rules"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#quota-rules",children:"Quota rules"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#host-volume-rules",children:"Host Volume rules"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#plugin-rules",children:"Plugin rules"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#generate-user-token",children:"Generate User Token"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#application-developer",children:"Application Developer"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#production-operations",children:"Production Operations"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#generate-nomad-tokens-with-hashicorp-vault-wip",children:"Generate Nomad Tokens with HashiCorp Vault (WIP)"})}),"\n"]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["Continuation of ",(0,i.jsx)(n.a,{href:"/docs/DevOps/Hashicorp/2022-05-18-hashicorp-dojo-nomad-adding-encryption/2022-05-18",children:"Hashicorp Nomad Dojo"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"nomad-acl-system",children:"Nomad ACL System"}),"\n",(0,i.jsx)(n.h3,{id:"core-objects",children:"Core objects"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Tokens"}),": Are either ",(0,i.jsx)(n.code,{children:"management"})," or ",(0,i.jsx)(n.code,{children:"client"}),' types. The management tokens are effectively "root" in the system and can perform any operation (',(0,i.jsx)(n.em,{children:"see Capabilities below"}),"). The client tokens are associated with one or more ACL policies which grant specific capabilities."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Policies"}),": Consist of a set of rules defining the capabilities or actions to be granted. The rules define the capabilities of a Nomad ACL token for accessing the objects in a Nomad cluster, objects like namespaces, node, agent, operator, quota, etc."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Capabilities"}),": Set of actions that can be performed including listing jobs, submitting jobs, querying nodes, etc."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"enable-acls-on-nomad-servers",children:"Enable ACLs on Nomad servers"}),"\n",(0,i.jsx)(n.p,{children:"Set the enabled value of the acl stanza to true. The acl stanza is a top-level stanza:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"acl {\n  enabled = true\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"Add these lines to all servers and restart the Nomad service."}),"\n",(0,i.jsx)(n.h3,{id:"stage-a-permissive-anonymous-policy",children:"Stage a Permissive Anonymous Policy"}),"\n",(0,i.jsx)(n.p,{children:"Once the ACL system is enabled, you need to generate the initial token. This first management token is used to bootstrap the system. Care should be taken not to lose all of your management tokens. If you do, you will need to re-bootstrap the ACL subsystem."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["Once the ",(0,i.jsx)(n.code,{children:"nomad acl bootstrap"})," command is run, Nomad's default-deny policy will become enabled. You should have an acceptable anonymous policy prepared and ready to submit immediately after bootstrapping."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Create a file named ",(0,i.jsx)(n.code,{children:"anonymous.policy.hcl"})," with this HCL content. You can use this as a transitional anonymous policy, which will minimize time in 
1which requests can not be submitted to the cluster once you bootstrap:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'namespace "*" {\n  policy       = "write"\n  capabilities = ["alloc-node-exec"]\n}\n\nagent {\n  policy = "write"\n}\n\noperator {\n  policy = "write"\n}\n\nquota {\n  policy = "write"\n}\n\nnode {\n  policy = "write"\n}\n\nhost_volume "*" {\n  policy = "write"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"run-the-bootstrap-command",children:"Run the Bootstrap Command"}),"\n",(0,i.jsxs)(n.p,{children:["Once the initial bootstrap is performed, it cannot be performed again unless the ",(0,i.jsx)(n.a,{href:"https://learn.hashicorp.com/tutorials/nomad/access-control-bootstrap#re-bootstrap-acl-system",children:"reset"})," procedure is complete. Make sure to save this AccessorID and SecretID. The bootstrap token is a management type token, meaning it can perform any operation."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"nomad acl bootstrap\nAccessor ID  = 5b7fd453-d3f7-6814-81dc-fcfe6daedea5\nSecret ID    = 9184ec35-65d4-9258-61e3-0c066d0a45c5\nName         = Bootstrap Token\nType         = management\nGlobal       = true\nPolicies     = n/a\nCreate Time  = 2022-06-15 04:04:46.571360464 +0000 UTC\nCreate Index = 7\nModify Index = 7\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Accessor ID"})," - The public identifier for a specific token. It can be used to look up information about a token or to revoke a token."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Secret ID"})," - Used to make requests to Nomad and should be kept private"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Name (optional)"})," - A user-supplied identifier."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type"})," - Shows the type of the token. Management tokens are used for administration and can be thought of as root-level tokens. Client tokens are used for applications and can have policies assigned to them at creation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Global"})," - (",(0,i.jsx)(n.code,{children:"bool"}),") Indicates whether or not the token was created with the --global flag. Global tokens are replicated from the authoritative region to other connected regions in the cluster."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Policies"})," - (",(0,i.jsx)(n.code,{children:"string"}),") A list of the policies assigned to the token."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Create Time"})," - Wall clock time on the Nomad server leader when the token was generated."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Create/Modification index"})," - Used by Nomad internally to determine when a token was created and/or modified relative to other system events."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"using-the-management-token",children:"Using the Management Token"}),"\n",(0,i.jsxs)(n.p,{children:["We are now locked out from using the CLI if we don't provide a management ACL Token with every request. To make this more comfortable we can add it to our shell config, e.g. ",(0,i.jsx)(n.code,{children:"~/.bashrc"})," or ",(0,i.jsx)(n.code,{children:"./zshrc"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export NOMAD_TOKEN="9184ec35-65d4-9258-61e3-0c066d0a45c5"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, we are now also locked out from using the Nomad UI and have to provide the ",(0,i.jsx)(n.strong,{children:"Secret ID"}),":"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Hashicorp Nomad ACL System",src:o(709331).A+"",width:"1101",height:"458"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Hashicorp Nomad ACL System",src:o(913720).A+"",width:"1100",height:"555"})}),"\n",(0,i.jsx)(n.h3,{id:"deploy-your-anonymous-policy",children:"Deploy your anonymous policy"}),"\n",(0,i.jsx)(n.p,{children:"Next, install the anonymous policy with the nomad acl policy apply command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'nomad acl policy apply -description "Anonymous policy (full-access)" anonymous anonymous.policy.hcl\n'})}),"\n",(0,i.jsx)(n.p,{children:"You can verify that the policy is active by e.g. un-setting the token in your Nomad UI - you should now be able to access everything again without providing any tokens."}),"\n",(0,i.jsx)(n.h3,{id:"create-management-tokens-for-other-regions",children:"Create Management Tokens for Other Regions"}),"\n",(0,i.jsx)(n.p,{children:"Once you have bootstrapped ACLs on the servers of the authoritative region, you can create the replication tokens for all of the non-authoritative regions in a multi-region configuration. Create the replication token with the nomad acl token create command."}),"\n",(0,i.jsx)(n.p,{children:'Use the -global flag on the nomad acl token create command or set the "Global" parameter to true in y
1our Create Token API call to create global tokens:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'nomad acl token create -type="management" -global=true -name="Cluster Replication Token"                            \nAccessor ID  = ec175d30-26ea-4a54-4850-45f833acece5\nSecret ID    = 9e2bb5ed-b3af-6bf3-5bbc-16dc684c5c31\nName         = Cluster Replication Token\nType         = management\nGlobal       = true\nPolicies     = n/a\nCreate Time  = 2022-06-15 04:38:21.360199318 +0000 UTC\nCreate Index = 11462\nModify Index = 11462\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Nomad has two token types: ",(0,i.jsx)(n.code,{children:"local"})," and ",(0,i.jsx)(n.code,{children:"global"}),". Local tokens are created and stored within the current Nomad region. However, for multi-region clusters, you can also create global tokens which are created in the authoritative region and replicated to the other regions."]}),"\n",(0,i.jsx)(n.p,{children:"Tokens can be deleted using the CLI:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"nomad acl token delete 9e2bb5ed-b3af-6bf3-5bbc-16dc684c5c31\n"})}),"\n",(0,i.jsx)(n.h3,{id:"generate-a-client-token",children:"Generate a Client Token"}),"\n",(0,i.jsx)(n.p,{children:'Create a client token called "client1" that is associated with the policies "app1" and "app2". It does not matter that these policies do not yet exist. Nonexistent policies provide no capabilities to a token, but they will not cause an error:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'nomad acl token create -name="client1" -policy="app1" -policy="app2"\nAccessor ID  = a7bef400-a66c-d163-52c4-5ff4978f19b8\nSecret ID    = 950e462b-b333-dd52-1e18-76837e9b97fa\nName         = client1\nType         = client\nGlobal       = false\nPolicies     = [app1 app2]\nCreate Time  = 2020-01-23 20:10:11.600915 +0000 UTC\nCreate Index = 19\nModify Index = 19\n'})}),"\n",(0,i.jsx)(n.h2,{id:"nomad-acl-policies",children:"Nomad ACL Policies"}),"\n",(0,i.jsx)(n.p,{children:"An ACL policy contains one or more rules. Rules contain coarse-grained policy dispositions. Rules typically have several policy dispositions:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read"}),": allow the resource to be read but not modified"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write"}),": allow the resource to be read and modified"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"deny"}),": do not allow the resource to be read or modified. Deny takes precedence when multiple policies are associated with a token."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"list"}),": allow the resource to be listed but not inspected in detail. Applies only to plugins."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Namespace rules are keyed by the namespace name they apply to. When no namespace is specified, the ",(0,i.jsx)(n.code,{children:"default"})," namespace is the one used."]}),"\n",(0,i.jsx)(n.p,{children:"In addition to the coarse-grained policy disposition, the namespace stanza allows setting a more fine grained list of capabilities. This includes:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"deny"})," - When multiple policies are associated with a token, deny will take precedence and prevent any capabilities."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"list-jobs"})," - Allows listing the jobs and seeing coarse grain status."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"parse-job"})," - Allows parsing a job from HCL to JSON."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read-job"})," - Allows inspecting a job and seeing fine grain status."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"submit-job"})," - Allows jobs to be submitted or modified."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"dispatch-job"})," - Allows jobs to be dispatched"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read-logs"})," - Allows the logs associated with a job to be viewed."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read-fs"})," - Allows the filesystem of allocations associated to be viewed."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"alloc-exec"})," - Allows an operator to connect and run commands in running allocations."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"alloc-node"}),"-exec - Allows an operator to connect and run commands in allocations running without filesystem isolation, for example, raw_exec jobs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"alloc-lifecycle"})," - Allows an operator to stop individual allocations manually."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"csi-register"}),"-plugin - Allows jobs to be submitted that register themselves as CSI plugins."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"csi-write"}),"-volume - Allows CSI volumes to be registered or deregistered."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"csi-read"}),"-volume - Allows inspecting a CSI volume and seeing fine grain status."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"csi-list"}),"-volume - Allows listing CSI volumes and seeing coarse grain status."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"csi-mount"}),"-volume - Allows jobs to be submitted that claim a CSI volume."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"list-scaling"}),"-policies - Allows listing scaling policies."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read-scaling"}),"-policy - Allows inspecting a scaling policy."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"read-job"}),"-scaling - Allows inspecting the current scaling of a job."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"scale-job"}),": Allows scaling a job up or down."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sentinel-override"})," - Allows soft mandatory policies to be overridden."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'namespace "default" {\n  policy = "write"\n}\n\nnamespace "testing" {\n  policy       = "read"\n  capabilities = ["submit-job","list-jobs","read-job"]\n}\n\nnamespace "sensitive" {\n  policy = "read"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"agent-rules",children:"Agent rules"}),"\n",(0,i.jsxs)(n.p,{children:["The agent rule controls access to the utility operations in the ",(0,i.jsx)(n.a,{href:"https://nomadproject.io/api-docs/agent/",children:"Agent API"}),", such as join and leave. Agent rules are specified for all agents using the agent key:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'agent {\n  policy = "write"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"operator-rules",children:"Operator rules"}),"\n",(0,i.jsxs)(n.p,{children:["The operator rule controls access to the ",(0,i.jsx)(n.a,{href:"https://nomadproject.io/api-docs/operator/",children:"Operator API"}),". Operator rules look like:"]}
1),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'operator {\n  policy = "read"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"quota-rules",children:"Quota rules"}),"\n",(0,i.jsxs)(n.p,{children:["The quota policy controls access to the quota specification operations in the ",(0,i.jsx)(n.a,{href:"https://nomadproject.io/api-docs/quotas/",children:"Quota API"}),", such as quota creation and deletion. Quota rules are specified for all quotas using the quota key:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'quota {\n  policy = "write"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"host-volume-rules",children:"Host Volume rules"}),"\n",(0,i.jsx)(n.p,{children:"The host_volume policy controls access to mounting and accessing host volumes."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'host_volume "*" {\n  policy = "write"\n}\n\nhost_volume "prod-*" {\n  policy = "deny"\n}\n\nhost_volume "prod-ca-certificates" {\n  policy = "read"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"plugin-rules",children:"Plugin rules"}),"\n",(0,i.jsx)(n.p,{children:"The plugin policy controls access to CSI plugins, such as listing plugins or getting plugin status. Plugin rules are specified for all plugins using the plugin key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'plugin {\n  policy = "read"\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["For more examples ",(0,i.jsx)(n.a,{href:"https://learn.hashicorp.com/tutorials/nomad/access-control-policies?in=nomad/access-control#acl-policy-specification",children:"hit the docs"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"generate-user-token",children:"Generate User Token"}),"\n",(0,i.jsx)(n.h3,{id:"application-developer",children:"Application Developer"}),"\n",(0,i.jsx)(n.p,{children:"The application developer needs to be able to deploy an application into the Nomad cluster and control its lifecycle. Application developers are allowed to fetch logs from their running containers:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'namespace "default" {\n  policy = "read"\n  capabilities = ["submit-job","dispatch-job","read-logs"]\n}\n'})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'nomad acl policy apply -description "Application Developer policy" app-dev app-dev.policy.hcl\n\nnomad acl token create -name="App-dev token" -policy=app-dev -type=client | tee app-dev.token\n'})}),"\n",(0,i.jsx)(n.h3,{id:"production-operations",children:"Production Operations"}),"\n",(0,i.jsx)(n.p,{children:"The production operations team needs to be able to perform cluster maintenance and view the workload, including attached resources like volumes, in the running cluster. But should not be allowed to run or stop jobs in the cluster."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'namespace "default" {\n  policy = "read"\n}\n\nnode {\n  policy = "write"\n}\n\nagent {\n  policy = "write"\n}\n\noperator {\n  policy = "write"\n}\n\nplugin {\n  policy = "list"\n}\n\n'})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'nomad acl policy apply -description "Production Operations policy" prod-ops prod-ops.policy.hcl\n\nnomad acl token create -name="Test prod-ops token" -policy=prod-ops -type=client | tee prod-ops.token\n'})}),"\n",(0,i.jsx)(n.h2,{id:"generate-nomad-tokens-with-hashicorp-vault-wip",children:"Generate Nomad Tokens with HashiCorp Vault (WIP)"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://learn.hashicorp.com/tutorials/nomad/vault-nomad-secrets?in=nomad/access-control",children:"Generate Nomad Tokens with HashiCorp Vault"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},709331(e,n,o){const s=o.p+"assets/images/Hashicorp_Nomad_ACL_System_01-871a4e2d202b71ca98f173498eab3075.png";o.d(n,["A",0,s])},913720(e,n,o){const s=o.p+"assets/images/Hashicorp_Nomad_ACL_System_02-0fc968195448dd99041d01f5e9d7e83b.png";o.d(n,["A",0,s])},963697(e,n,o){const s=o.p+"assets/images/photo-kt443t6d_64hdh43hfh6dgjdfhg4_d-6c1edb088dfea3a7d39f8eebb8e9dc23.jpg";o.d(n,["A",0,s])},28453(e,n,o){o.d(n,{R:()=>l,x:()=>t});var s=o(296540);const i={},a=s.createContext(i);function l(e){const n=s.useContext(a);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.