Providing TLS certificate for squid service fails. Sandboxing issue?

I’ve configured

services.squid = {
    enable = true;
    configText = builtins.readFile ./conf-squid;
  };

with squid.conf

http_port 3128 ssl-bump cert=/var/cache/squid/squidCA.pem generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

and added a certificate in /var/cache/squid (I would prefer etc? but how can I safely add a TLS key so it isn’t stored in nix/store readable to all?)

but nixos-rebuild switch fails with

sudo chmod 777 -R /var/cache/squid
sudo -u nobody cat /var/cache/squid/squidCA.pem

2026/05/17 14:28:48| ERROR: unable to load certificate file ‘/var/cache/squid/squidCA.pem’: error:80000002:system library::No such file or directory
2026/05/17 14:28:48| WARNING: ‘HTTP_port [::]:3128’ missing certificate in ‘/var/cache/squid/squidCA.pem’

which also happens with

sudo chmod 777 -R /var/cache/squid

despite this works

sudo -u nobody cat /var/cache/squid/squidCA.pem

so I assume some sandboxing is happening.

How can I enter the sandbox and observe the filesystem?

How can I make folders accessible, for configuration, and for data files?

I assumed /var/cache would be accessible since it’s used by the service itself.

So I’m confused about what’s happening here.

There is no sandboxing for this service. Since it is not sandboxed, you can use any /etc path if you want (or really anything else), though the generic intended mechanism by systemd is to use a credential - that also works with sandboxed services.

Untested example of how to use a credential for squid's TLS key
{
  systemd = {
    # The credential stores aren't created by
    # default, so if you want to use systemd
    # creds you need to put this in your config
    # *somewhere*, though the same file as 
    # your squid config is probably not the best.
    tmpfiles.settings."10-credstore" = {
      "/etc/credstore".d = {
        user = "root";
        group = "root";
        mode = "0700";
      };

      "/etc/credstore.encrypted".d = {
        user = "root";
        group = "root";
        mode = "0700";
      };
    };

    # This on the other hand tells systemd
    # to make the credential available to squid,
    # and it probably *should* be in the same file
    # as your squid config
    services.squid.serviceConfig.LoadCredentialEncrypted = "squid-tls-key";
  };
}

And then to actually install this credential on your host, you need to run this command:

# systemd-creds encrypt your-key.pem /etc/credstore.encrypted/squid-tls-key

You also need to change the key path:

cert=/run/credentials/squid.service/squid-tls-key

You can delete the original .pem file afterwards if you don’t need another copy.

If that’s too imperative for you, you can of course do whatever you want to get that file there at runtime. If you generate the key by hand, you could for example instead write a systemd service that generates it on boot (use wantedBy and after systemd-random-seed.service for entropy purposes) and puts it in the same location using the systemd-creds command.

Or, of course, you could use sops-nix or whatever to distribute it in encrypted form. I think this is bad practice, though, keys should ideally never leave the host they are used on, and sops-nix & co. encourage that. I’d just copy the file over by hand, or use vault (ideally integrated with the systemd creds socket feature) when that stops scaling.

Note that the secret options of various NixOS modules really don’t work well with systemd creds, so you often have to modify the services a little. This is unfortunate, I hope to improve this situation at some point.

As for non-secret state, systemd also makes a variety of options available for this. Typically, the relevant data directories end up living in subdirectories of /var/lib/private, but cache directories would for example be in the /var/cache you mention (though /var/cache is definitely not the right place to put a file that should be persisted).


I don’t use squid, so I don’t know, but this seems fishy to me:

The error complains about a missing certificate, not key, so maybe you need to specify the certificate differently. But that’s just my 2c, this part is likely wrong.

Alternatively you can strace the daemon to figure out what file it’s trying to read when it gets that error.