NACM authorization

I am trying to deny update of one of the fields on my Yang model. I added the following sections in to aaa_init.xml

  <rule>
    <Name>ltm</name>
    <module-name>ltm</module-name>
    <path>/ltm/node</path>
    <access-operations>create update read delete</access-operations>
    <action>permit</action>
  </rule>
  <rule>
    <name>node</name>
    <module-name>node</module-name>
    <path>/ltm/node/address</path>
    <access-operations>update</access-operations>
    <action>deny</action>
  </rule>

But that is not working.

It works only in case I apply no update on entire “node” and not specific field of the node (with write-default set to deny)

  <rule>
    <Name>ltm</name>
    <module-name>ltm</module-name>
    <path>/ltm/node</path>
    <access-operations>create read delete</access-operations>
    <action>permit</action>
  </rule>

You might want to switch the order of the rules you have.
The first rule that matches the operation is the rule that is applied.

In the example you specified, the rule Ltm will trump any other specific rule below it, meaning any operation on any field under /Ltm/node/*

I changed the order, but got same result.
How I can enable debug?
May be my path is incorrect?
May be it should be /ltm/node[name]/address instead of /ltm/node/address?

You should use the path /ltm/node/address so that the rule match all address elements for all nodes.

But note that when you login using the confd_cli -u my-username the nacm rule won’t apply since you may not belong to the user group you defined in the rule.

Try logging in using NETCONF or SSH when you test your nacm rule. For example:
ssh -l my-username 127.0.0.1 -p 2024

Demo of difference between confd_cli and SSH:

$ confd_cli -u oper
# id
user = oper(501), gid=20, groups=oper,staff,access_bpf,everyone,localaccounts,_appserverusr,admin,_appserveradm,_lpadmin,_appstore,_lpoperator,_developer,com.apple.access_screensharing,com.apple.access_ssh, gids=12,20,33,61,79,80,81,98,100,204,398,399,503
# exit
$ ssh -l oper 127.0.0.1 -p 2024
oper@127.0.0.1's password: 
# id
user = oper(9000), gid=20, groups=oper, gids=
#

I am testing using “make cli-c”, I assume above comment regarding username is not valid.
Tried using /ltm/node/address with deny as first rule, still not working as expected.

My previous comment is then valid since “make cli-c” in the ConfD examples is actually running confd_cli.

But, in here the confd_cli flag for groups is specified, so if your rule applies to the group “admin” then the rule should trigger.

From a Makefile in one of the examples:

cli-c:
        $(CONFD_DIR)/bin/confd_cli --user=admin --groups=admin \
                --interactive --host $(CONFD_HOST) -C || echo Exit

My Makefile includes the line you mentioned above.
The rule list in that aaa_init.xml file starts as follows:

<rule-list>
 <name>any-group</name>
 <group>*</group>

Can you post the result of a show of your NACM configuration when loaded into ConfD?

E.g.

$ make cli-c 
# show running-config nacm rule-list

I suspect that you have a rule-list for the admin group above (i.e. with higher priority) your rule-list for “any-group”?

hype# show running-config nacm rule-list
--------------------------^
syntax error: element does not exist

Only thing related to AAA on configuration is:

aaa authentication users user admin
uid 9000
gid 100
password $1$yFX0ZR8p$Bo6O.kW2lwRLdmRqtwSbm/
ssh_keydir /var/confd/homes/admin/.ssh
homedir /var/confd/homes/admin
!

Looks like the admin rule-list from the NACM configuration in the default aaa_init.xml is missing?

I.e. this part:

<rule-list>
  <name>admin</name>
  <group>admin</group>
  <rule>
    <name>any-access</name>
    <action>permit</action>
  </rule>
</rule-list>

Now it does show NACM section in running config, buts still does not function properly (allow to update address field)

hype# show running-config nacm rule-list
nacm rule-list admin
group [ admin ]
rule any-access
action permit
!
!
nacm rule-list any-group
group [ * ]
rule tailf-aaa-authentication
module-name tailf-aaa
path /aaa/authentication/users/user[name=‘$USER’]
access-operations read,update
action permit
!
rule tailf-aaa-user
module-name tailf-aaa
path /user[name=‘$USER’]
access-operations create,read,update,delete
action permit
!
rule tailf-webui-user
module-name tailf-webui
path /webui/data-stores/user-profile[username=‘$USER’]
access-operations create,read,update,delete
action permit
!
rule node
module-name node
path /ltm/node/address
access-operations update
action deny
!
rule ltm
module-name ltm
path /ltm/*
access-operations create,read,update,delete
action permit
!
!
hype# config
Entering configuration mode terminal
hype(config)# ltm node cpf1
hype(config-node-cpf1)# address
() (10.1.91.50): 1.1.1.1
hype(config-node-cpf1)#

With the rule-lists setup that you have right now, if you login as the ‘oper’ user which belongs to the ‘oper’ group, you will see the ‘node’ rule kick in.

If you want the ‘admin’ user which belongs to the ‘admin’ group be affected by the ‘node’ rule, you must move the ‘nacm rule-list admin’ below / after the ‘nacm rule-list any-group’ in your aaa_init.xml or using the ‘move’ command in the CLI.

My running-config nacm looks like this:

hype# show running-config nacm
nacm enable-nacm true
nacm read-default permit
nacm write-default deny
nacm exec-default deny
nacm groups group admin
user-name [ admin private ]
!
nacm groups group oper
user-name [ oper public ]
!
nacm rule-list any-group
group [ * ]
rule tailf-aaa-authentication
module-name tailf-aaa
path /aaa/authentication/users/user[name=‘$USER’]
access-operations read,update
action permit
!
rule tailf-aaa-user
module-name tailf-aaa
path /user[name=‘$USER’]
access-operations create,read,update,delete
action permit
!
rule tailf-webui-user
module-name tailf-webui
path /webui/data-stores/user-profile[username=‘$USER’]
access-operations create,read,update,delete
action permit
!
rule node
module-name node
path /ltm/node/address
access-operations update
action deny
!
rule ltm
module-name ltm
path /ltm/*
access-operations create,read,update,delete
action permit
!
!
nacm rule-list admin
group [ admin ]
rule any-access
action permit
!
!

User admin still can modify the address field.
Then I tried to change my Makefile, in order for cli-c to start with “oper” privileges

cli-c:
$(CONFD_DIR)/bin/confd_cli -C --user=oper --groups=oper
–interactive || echo Exit

Still same result, “oper” also can modify the address field.

That should work. Maybe you did a ‘create’ of a list entry, i.e. the list entry did not exist when you set the address field, and not an ‘update’, i.e. the list entry existed when you set the address field?

Here is a working example where I first only deny ‘update’ and then add to the rule to deny ‘create’ too so that you can compare with your project:

$ more example.yang
module example {
  namespace "http://tail-f.com/ns/example/config";
  prefix example;

  container Ltm {

    list node {
      key name;
      leaf name {
        type string;
      }
      leaf address {
        type uint32;
      }
    }
  }
}
$ make cli-c
/tailf/releases/confd-basic-5.4.darwin.x86_64/../../confd-basic-5.4/bin/confd_cli --user=admin --groups=admin \
		--interactive --host 127.0.0.1 -C || echo Exit
Welcome to ConfD Basic

127.0.0.1# id
user = admin(501), gid=20, groups=admin, gids=12,20,33,61,79,80,81,98,100,204,398,399,503
127.0.0.1# config
Entering configuration mode terminal
admin(config)# show full-configuration nacm
nacm enable-nacm       true
nacm read-default      permit
nacm write-default     permit
nacm exec-default      permit
nacm enable-external-groups true
nacm cmd-read-default  permit
nacm cmd-exec-default  permit
nacm groups group admin
 user-name [ admin private ]
!
nacm groups group oper
 user-name [ oper public ]
!
nacm rule-list any-group
 group [ * ]
 rule test-rule
  module-name       *
  path              /Ltm/node/address
  access-operations update
  action            deny
  context           *
 !
 rule tailf-aaa-authentication
  module-name       tailf-aaa
  path              /aaa/authentication/users/user[name='$USER']
  access-operations read,update
  action            permit
  context           *
 !
 rule tailf-aaa-user
  module-name       tailf-aaa
  path              /user[name='$USER']
  access-operations create,read,update,delete
  action            permit
  context           *
 !
 rule tailf-webui-user
  module-name       tailf-webui
  path              /webui/data-stores/user-profile[username='$USER']
  access-operations create,read,update,delete
  action            permit
  context           *
 !
!
nacm rule-list admin
 group [ admin ]
 rule any-access
  module-name       *
  access-operations *
  action            permit
  context           *
 !
!
admin(config)# show full-configuration Ltm 
% No entries found.
admin(config)# Ltm node test1 address 99
admin(config-node-test1)# commit
Commit complete.
admin(config-node-test1)# exit
admin(config)# show full-configuration Ltm
Ltm node test1
 address 99
!
admin(config)# Ltm node test1 address 100 
Error: access denied
admin(config-node-test1)# exit
admin(config)# nacm rule-list any-group rule test-rule access-operations create,update
admin(config-rule-test-rule)# commit
Commit complete.
admin(config-rule-test-rule)# exit
admin(config-rule-list-any-group)# exit
admin(config)# exit
127.0.0.1# exit  
$ make cli-c
/Users/conny/tailf/releases/confd-basic-5.4.darwin.x86_64/../../confd-basic-5.4/bin/confd_cli --user=admin --groups=admin \
		--interactive --host 127.0.0.1 -C || echo Exit
Welcome to ConfD Basic

127.0.0.1# config 
Entering configuration mode terminal
admin(config)# Ltm node test2 address 199
Error: access denied       
admin(config-node-test2)# commit
Commit complete.
admin(config-node-test2)# exit
admin(config)# show full-configuration Ltm
Ltm node test1
 address 99
!
Ltm node test2
!
admin(config)# Ltm node test1 address 100 
Error: access denied
admin(config-node-test1)# exit
admin(config)# show full-configuration Ltm
Ltm node test1
 address 99
!
Ltm node test2
!
admin(config)#