A secret stored in Nexus with type: "file" is materialised to a real file on disk so you can hand its path to something that only accepts a path - a TLS certificate for nginx, a service-account JSON for a cloud client library, a private key for an SSH tool.
This is the one place the SDK puts credential material somewhere another process can reach, so the guarantees are worth stating precisely.
Permissions
Changed in v0.11.0.
Files are created with mode 0600 - readable and writable by the owning user only.
The mode is applied at creation, not by a chmod afterwards. A chmod-after leaves a window in which the file already exists with the process umask applied, and anything watching the directory can read it during that window.
Before v0.11.0 the file was written with Path.write_text, which takes no mode argument at all, so it inherited the process umask - typically 0644 in a shared /tmp, where every local user on the machine could read the secret. If you ran an affected version on a multi-tenant or shared host, treat any file-type secret it materialised as exposed and rotate it.
The SDK also opens the file with O_NOFOLLOW, so it refuses to write through a symlink planted at the target path.
Windows
There is no 0600 equivalent. The file inherits the temp directory ACL, which on a default single-user install is not world-readable but is not equivalent to 0600 either. This matches the other Nexus SDKs.
Isolation between clients
Changed in v0.11.0.
Each client instance materialises secrets to its own paths. Two clients in the same process holding the same secret get two files.
Previously the path came from the secret’s key and value alone, so both clients resolved to a single file - and whichever was closed first deleted it out from under the other. The survivor’s get_secret_file_path then returned a path to a file that no longer existed, usually surfacing much later as a confusing FileNotFoundError from whatever consumed it.
Lifecycle
- Written on the first sync that contains the secret, and rewritten when the value changes.
- The old file is removed when the value changes.
- Removed when the secret leaves the sync payload, or its type stops being
file.
- All remaining files are removed on
close().
Because cleanup happens in close(), use the client as a context manager (or call close() in a finally) so a clean shutdown leaves nothing on disk:
A hard kill (SIGKILL, a container OOM) skips cleanup and leaves the files. They are mode 0600 and in the temp directory, so the OS clears them on the usual schedule - but if your threat model cares, mount a tmpfs for TMPDIR.
Choosing the directory
The SDK writes to tempfile.gettempdir(), which honours TMPDIR on POSIX. Point it at a tmpfs or a dedicated per-service directory to keep secrets off a persistent disk:
Next