Browse documentation
Guides

Credentials

Keep keys outside source with opaque references, native operating system stores, injected environments, and an explicit managed file fallback.

aner.secrets gives an Aner program an opaque reference to a credential. Source code specifies a credential label or environment variable name; the native runtime resolves its value when the configured consumer uses it. A reference does not expose a raw String, export a value, or load a project file implicitly.

Keep a credential separate from source, notebooks, generated reports, and version control. For interactive development, prefer the native operating system credential service. For headless deployment, use a process environment injected by an external secret manager, or explicitly opt into Aner’s managed file fallback.

Storage choices

ReferenceStorageAvailability and boundary
secrets.stored("openai")Operating system credential serviceNative macOS Keychain and Windows Credential Manager adapters are implemented. Linux system storage is unavailable in this release.
secrets.env("OPENAI_API_KEY")Existing process environmentSupports deployment systems that inject credentials. Aner does not discover or load a .env file.
secrets.file("openai")Explicit managed Aner file storeAvailable on POSIX systems as a fallback. Windows uses its native system store. POSIX directories and files are owner only; values are plaintext on disk.

An environment variable is convenient for automation, but it is not an encrypted vault and may be inherited by child processes. The managed file store protects access permissions; it does not encrypt stored values. Operating system storage is a distinct choice with the platform service’s access policy. Native Windows support is implemented and has not yet been validated on a Windows host. System store behavior is subject to the local account and credential service policy; implementation availability is separate from host validation.

Set a credential with hidden input

Run the command in a local interactive terminal:

sh
aner secrets set openai

The command prompts for the value without echoing it. The default is --store system. Do not append a credential value to a command, paste it into source, or put it in a notebook cell. The command accepts a label; it does not accept a secret value as a command line argument. Automation may opt into --stdin to supply a value through standard input from its secret manager; interactive use keeps the hidden prompt.

Inspect configuration without displaying the value:

sh
aner secrets status openai

Remove the credential when it is no longer required:

sh
aner secrets delete openai

These commands manage Aner’s credential entry. Deleting an entry does not revoke the credential at its issuer; rotate or revoke it using that provider’s controls when needed. The credential name is a stable label that source can retain after the value changes. Managed labels contain at most 64 characters: letters, digits, underscores, periods, and hyphens, beginning with a letter or digit. Environment names contain at most 128 characters and follow identifier syntax. Credential values contain from 1 through 8192 visible ASCII bytes without whitespace or control characters.

Use a reference in Aner

aner
import aner.llm
import aner.secrets

let key = secrets.stored("openai")
let model = llm.client(provider: "openai", model: "gpt-4.1-mini", key: key)
let answer = model.generate("Explain the purpose of validation data.", max_tokens: 128)
print(answer.text())

Reference construction does not perform a provider request or return the credential value. The request resolves the reference through the selected store. Missing, empty, inaccessible, or invalid credentials produce a source located R3102 diagnostic; provider rejection produces a sanitized R3101 diagnostic. Credentials appear only in the native authorization path and are excluded from ordinary handle display and development inspection.

The same source can use an injected environment variable:

aner
import aner.secrets

let key = secrets.env("OPENAI_API_KEY")

Configure the process environment through the deployment system. Aner deliberately does not read .env files automatically: a working directory should not silently choose authenticated behavior. Explicit environment references also support external secret managers without coupling source to their storage format.

Headless Linux and the file fallback

A headless machine without a supported system store can opt into the managed file store:

sh
aner secrets set openai --store file
aner secrets status openai --store file

The matching source reference is explicit:

aner
import aner.secrets

let key = secrets.file("openai")

To remove the managed entry:

sh
aner secrets delete openai --store file

A file store label addresses a managed entry; it is not an arbitrary path. The default managed directory is .config/aner/secrets beneath the operating system account’s home directory. An explicit absolute ANER_SECRETS_DIR may select a separate private store for a container or isolated deployment; the same ownership, permission and symbolic link checks apply. It does not enable project file discovery. On POSIX systems the store directory must be owned by the current user with mode 0700, and credential files must be owned by that user with mode 0600. Unsafe ownership, permissions, or symbolic links are rejected. An isolated profile can be backed up or removed according to local policy; backups contain plaintext credentials and require the same care as the original store.

Explicit file storage is useful where an operating system vault is unavailable, but encrypted deployment storage or injected short lived credentials remain preferable when the environment provides them. Aner does not silently fall back from an unavailable system store to plaintext files.

API reference

CallResultResolution
secrets.stored(name: String)SecretRefManaged operating system credential entry.
secrets.env(name: String)SecretRefNamed variable in the current process environment.
secrets.file(name: String)SecretRefManaged owner only file entry.

SecretRef is an opaque native type. It has no raw value getter, implicit String conversion, serialization export, or method that prints the credential. A provider connection receives the reference and resolves it natively when needed. Current credential consumers are Language model connections and Model inference APIs. An LLM client resolves its credential for each authenticated provider request. An API listener resolves its inbound bearer credential once at startup and retains the resolved value in private memory while running. Changing or deleting that store entry does not revoke the already running listener's token; stop or restart the listener to apply rotation or removal. A restarted listener must resolve a valid configured credential before accepting requests. Use a dedicated inbound API credential separate from an upstream provider credential.

Observation and transport

A reference protects the credential, not every piece of application data. Plain prompt Strings and generated text explicitly extracted through answer.text() remain ordinary values; printing or capturing them can retain content in reports or notebooks. Opaque message, client, and response handles hide their content during ordinary inspection. Saved notebook output is separate from credential storage and should be reviewed before sharing.

The LLM module uses verified HTTPS for nonlocal connections. It rejects credentials embedded in URLs, follows no redirects, and does not use ambient HTTP proxy variables. Local loopback HTTP supports local inference and explicitly established tunnels. An IP address on a private network is not a substitute for encryption. Credentials and provider error bodies are not copied into diagnostics.

Credential storage does not grant a provider permission to use a dataset. Select endpoints, account policies, and allowed data deliberately before making a request. Production mode disables development recording while retaining the same authenticated inference behavior.

Time and space complexity

For a credential name of n bytes, constructing a SecretRef takes O(n) time and O(n) retained space. Name and credential size validation use bounded inputs. Environment resolution reads the selected value; file resolution reads bounded stored bytes; system store resolution is governed by the operating system service. No universal latency bound is assigned to an external credential service. Secret values are not part of the returned Aner object.

Aner documentation · Reference and guides