Access denied with NETCONF, not with CLI

Using confd-6.3.1

The security-admin user can show the aaa config via the CLI, and modify it:

    root@deploy-uas:/var/log# confd_cli -u security-admin -U 999 -G 22 -C -g security-admin
    Welcome to the ConfD CLI
    security-admin connected from 127.0.0.1 using console on deploy-uas
    deploy-uas#id
    user = security-admin(999), gid=22, groups=security-admin, gids=0
   deploy-uas#show running-config aaa
    <snip>
    aaa authentication users user security-admin
     uid        999
     gid        22
     password   $1$xd6gh0Ug$VBf2ao5dNtSsV40RTD6Wa/
     ssh_keydir /var/confd/homes/security-admin/.ssh
     homedir    /var/confd/homes/security-admin
    ! <snip> 

The security-admin user cannot show any config via NETCONF, access is denied, nor can it modify anything:

root@deploy-uas:/home/ubuntu# netconf-console --user=security-admin --password=cisco --get-config
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>protocol</error-type>
    <error-tag>access-denied</error-tag>
    <error-severity>error</error-severity>
  </rpc-error>
</rpc-reply>
root@deploy-uas:/home/ubuntu#

How come?

Here are the nacm definitions for security-admin:

nacm groups group security-admin
 user-name [ security-admin ]
!
nacm rule-list security-admin
 group [ security-admin ]
 rule tailf-securityadmin-crud
  module-name       tailf-aaa
  path              /
  access-operations create,read,update,delete
  action            permit
  context           *
 !
 rule tailf-securityadmin-nacm
  module-name       *
  path              /nacm:nacm
  access-operations read,update
  action            permit
  context           *
 !
 rule tailf-securityadmin-nacm-oper
  module-name       *
  path              /nacm:nacm/nacm:groups/nacm:group[name='oper']/nacm:user-name
  access-operations create,read,update,delete
  action            permit
  context           *
 !
 rule tailf-securityadmin-nacm-securityadmin
  module-name       *
  path              /nacm:nacm/nacm:groups/nacm:group[name='security-admin']/nacm:user-name
  access-operations create,read,update,delete
  action            permit
  context           *
 !
 rule tailf-securityadmin-nacm-uspadmin
  module-name       *
  path              /nacm:nacm/nacm:groups/nacm:group[name='uspadmin']/nacm:user-name
  access-operations create,read,update,delete
  action            permit
  context           *
 !
 rule any-access
  module-name       *
  access-operations *
  action            deny
  context           *
 !
!

Look for:

<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
...
    <exec-default>deny</exec-default>
...

or something like:

<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
...
      <rule>
        <name>deny-get-config</name>
        <rpc-name>get-config</rpc-name>
        <action>deny</action>
      </rule>
...

or something like:

<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
...
      <rule>
        <name>deny-all-rpcs</name>
        <rpc-name>*</rpc-name>
        <action>deny</action>
      </rule>
...

There is none of the above.

In the nacm definitions (pasted above) when I change the last rule:

 rule any-access
  module-name       *
  access-operations *
  action            deny
  context           *
 !

To this

 rule any-access
  module-name       *
  access-operations *
  action            permit
  context           *
 !

Then NETCONF works.

From RFC6536 https://tools.ietf.org/html/rfc6536#section-3.5.2:

...
          choice rule-type {
             description
               "This choice matches if all leafs present in the rule
                match the request.  If no leafs are present, the
                choice matches all requests.";
             case protocol-operation {
               leaf rpc-name {
...
             case data-node {
               leaf path {
...

So if you, like in your any-access rule, do not specify the rule type the rule will be applied to all rule-types - for example RPC’s like <get-config>.