Skip to content

profile::terraformer::plugin_cache: shared cache not group-writable for peer admin users (umask clamps the ACL mask) #283

Description

@akuzminsky

Summary

The shared Terraform provider plugin cache set up by profile::terraformer::plugin_cache (TF_PLUGIN_CACHE_DIR=/var/cache/terraform/plugins) is not writable by peer members of the admin group. Whichever admin user runs terraform first creates the provider dirs; a second admin user then gets Permission denied writing into them.

Observed on ip-10-1-1-168: works for aleks, fails for taha.

taha@ip-10-1-1-168:.../registry.terraform.io/hashicorp/aws$ mkdir tmp
mkdir: cannot create directory ‘tmp’: Permission denied

Root cause

The manifest's design assumption is stated in its own comment:

setgid so new entries inherit the admin group; the default ACL below adds the group-write that the umask would otherwise strip from nested dirs.

That assumption is incorrect. The default ACL is applied, but each newly-created provider dir's access mask comes out r-x, which clamps the effective group:admin permission back down to r-x:

$ getfacl /var/cache/terraform/plugins/registry.terraform.io/hashicorp/aws
# owner: aleks
# group: admin
# flags: -s-
group::rwx			#effective:r-x
group:admin:rwx			#effective:r-x
mask::r-x
default:group:admin:rwx
default:mask::rwx

Note the access mask::r-x vs default:mask::rwx. POSIX rule: a directory created under a parent that has a default ACL gets its access mask = default mask ∩ the group bits of the mode passed to mkdir. Terraform calls mkdir(…, 0777); with umask 022 the effective create mode is 0755 → group bits r-x → mask clamped to r-x. So the default ACL does not, and cannot, protect group-write against umask 022 — the umask re-clamps the mask on every dir Terraform creates.

Two compounding issues in the current manifest:

  1. The terraformer-plugin-cache-acl exec is guarded by unless and only runs at provision time, so it never repairs the mask on dirs Terraform creates afterward.
  2. The profile.d export sets TF_PLUGIN_CACHE_DIR but not a umask, so every interactive run uses the default 022.

Proposed fix

Set umask 002 for the context that runs Terraform, so mkdir requests 0775 → group bits rwx → mask rwxgroup:admin effective rwx. Combined with the existing setgid bit this is self-sustaining and the ACL exec becomes redundant.

Simplest change: add umask 002 to the managed /etc/profile.d/terraform-plugin-cache.sh:

content => "# Managed by Puppet (profile::terraformer::plugin_cache)\numask 002\nexport TF_PLUGIN_CACHE_DIR=${cache_dir}\n",

Note profile.d only covers interactive login shells — if Terraform is ever invoked from cron/systemd on this host, set the umask in that unit/job too. Keeping the default-ACL exec is harmless as defense-in-depth, but it's the umask that actually fixes it.

One-time repair of the current live host

sudo chmod -R g+w /var/cache/terraform
sudo setfacl -R -m m::rwx /var/cache/terraform   # reset the clamped access masks

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions