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

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions