Skip to main content
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.13.0. Files are created with mode 0600 - readable and writable by the owning user only - inside a private per-client directory created 0700. The mode is applied at creation, not by a chmod afterwards. A chmod-after leaves a window in which the file already exists under the process umask, and anything watching the directory can read it during that window. The file is created exclusively (O_EXCL, after removing any leftover at the path), so the mode applies on every write - a pre-existing file or a planted symlink, live or dangling, never receives the secret at its own permissions. O_NOFOLLOW additionally refuses to write through a symlink racing back in.

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.13.0. Each client instance owns a private directory (tempfile.mkdtemp: mode 0700, unguessable name), created lazily when the first file-type secret arrives - a client that never sees one leaves nothing on disk. Two clients holding the same secret therefore get two files in two directories, so one client’s close() never removes a file the other is still handing out, and nothing can be planted at a path that does not exist until the directory is created owner-only.

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 - and the private directory - are removed on close().
  • A process-level atexit backstop (v0.13.0) removes whatever a process leaves behind without close(); an eager close() is still preferred, since it cleans up immediately rather than at interpreter shutdown.
The backstop is deliberately not a signal handler - a library must not change how your application responds to Ctrl-C - so a signal-terminated process (SIGKILL, a container OOM) still leaves the files. They are mode 0600 in an owner-only directory, so the exposure is persistence, not readability - but if your threat model cares, mount a tmpfs for TMPDIR.

Choosing the directory

The per-client directory is created under 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