Change in behavior: Directories are now created with 700 instead of 755

Posted by Nick Anderson
December 16, 2022

In the upcoming release of CFEngine 3.21.0 there is a change in behavior with respect to default permissions of created directories. From 3.21.0 and later directories will be created with read, write, execute permissions only for the file owner. No permissions are granted for group or other.

This change improves the default security posture to make sure that only the user executing CFEngine (typically root) will have access to content in newly created directories. This also aligns default directory permissions with default file permissions.

Illustrating the change in behavior

This policy snippet illustrates the change in behavior:

bundle agent __main__
{
  files:
      "/tmp/a/promised/directory/."
        create => "true";

  reports:
      "CFEngine $(sys.cf_version)";
      "Directory has $(with)"
        with => concat( "permoct='",
                        filestat( "/tmp/a/promised/directory/.",
                                  "permoct"  ), "', ",
                        "permstr='",
                        filestat( "/tmp/a/promised/directory/.",
                                  "permstr"  ), "'" );
}

On versions prior to 3.21.0 we see that newly created directories are grant access to both group and other.

[root@hub ~]# cf-agent -KIf ./example-default-directory-permissions.cf
    info: Created directory '/tmp/a/promised/directory/.'
R: CFEngine 3.18.0
R: Directory has permoct='755', permstr='drwxr-xr-x'

On 3.21.0 and later we see that only the directory owner has permission:

[root@hub ~]# cf-agent -KIf ./example-default-directory-permissions.cf
    info: Created directory '/tmp/a/promised/directory/.'
R: CFEngine 3.21.0
R: Directory has permoct='700', permstr='drwx------'

Explicit permissions

The change in default does not affect the behavior when promising explicit permissions. The directory is initially created with the default permissions and then immediately changed to comport with the explicit permissions promised.

bundle agent __main__
{
  files:
      "/tmp/a/promised/directory/."
        create => "true",
        perms => permoct( 655 );

  reports:
      "CFEngine $(sys.cf_version)";
      "Directory has $(with)"
        with => concat( "permoct='",
                        filestat( "/tmp/a/promised/directory/.",
                                  "permoct"  ), "', ",
                        "permstr='",
                        filestat( "/tmp/a/promised/directory/.",
                                  "permstr"  ), "'" );
}
body perms permoct( oct )
{
        mode => "$(oct)";
        rxdirs => "false";
}

The output below illustrates the behavior on 3.21.0.

[root@hub ~]# cf-agent -KIf ./example-explicit-directory-permissions.cf
    info: Created directory '/tmp/a/promised/directory/.'
    info: Object '/tmp/a/promised/directory' had permissions 0700, changed it to 0655
R: CFEngine 3.21.0
R: Directory has permoct='655', permstr='drw-r-xr-x'

And running on 3.18.0 we can see that the behavior when promising explicit permissions is identical except for the initial default:

[root@hub ~]# cf-agent -KIf ./example-explicit-directory-permissions.cf
    info: Created directory '/tmp/a/promised/directory/.'
    info: Object '/tmp/a/promised/directory' had permissions 0755, changed it to 0655
R: CFEngine 3.18.0
R: Directory has permoct='655', permstr='drw-r-xr-x'