# How to Manage API Credentials and Use Keyring Integration in DeepSeek-Reasonix

> Learn how to manage API credentials in DeepSeek-Reasonix using environment variables and OS keyring integration. Securely store and access your keys with CredentialResolver.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: how-to-guide
- Published: 2026-06-24

---

**DeepSeek-Reasonix stores API keys in a global `.env` file with optional OS keyring integration, using a hierarchical resolution system that checks environment variables, project files, and the system keyring via the `CredentialResolver` type.**

DeepSeek-Reasonix provides a secure, flexible credential management system for API keys and secrets. The system supports multiple storage backends including environment variables, project-specific `.env` files, and OS-native keyring integration through the `go-keyring` library. Understanding how to configure and interact with these credential sources is essential for securely managing provider API keys in your workflows.

## Understanding the Credential Resolution System

The credential system centers on the `CredentialResolution` struct defined in [`internal/config/credentials.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/credentials.go). This type tracks not only the resolved value but also its provenance and any shadowed sources.

```go
type CredentialResolution struct {
    Name     string           `json:"name"`
    Set      bool             `json:"set"`
    Value    string           `json:"-"`
    Source   CredentialSource `json:"source,omitempty"`
    Shadowed []CredentialSource `json:"shadowed,omitempty"`
}

```

The resolver checks credentials in the following priority order:

- **Environment variables** – Process environment (`os.Getenv`)
- **Project `.env`** – `<workspace-root>/.env` (kind: `project_env`)
- **Global Reasonix credentials** – `$HOME/.env` (kind: `credentials`)
- **Home `.env`** – Legacy location in `$HOME/.env` (kind: `home_env`)
- **OS keyring** – System keyring entry (kind: `keyring` or `legacy_credentials`)

When the `CredentialResolver` (scoped to a workspace root) processes a lookup, it caches results to ensure UI components receive consistent values for the same key.

## Configuring the Credential Store Mode

DeepSeek-Reasonix determines where to store new credentials through a three-tier selection process implemented in `credentialsStoreMode()`:

1. **Explicit environment variable** – Set `REASONIX_CREDENTIALS_STORE` to `auto`, `keyring`, or `file`
2. **User configuration** – The `credentials_store` field in `~/.reasonix/config.toml`
3. **Default behavior** – Falls back to `auto` mode

When set to `keyring`, the system delegates storage to the OS-native keyring using the `github.com/zalando/go-keyring` library (version `v0.2.8` as declared in `go.mod`).

## Implementing Keyring Integration

The keyring implementation uses platform-specific abstraction files to handle OS differences.

On Unix-like systems, [`internal/config/credentials_keyring_unix.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/credentials_keyring_unix.go) contains the real implementation targeting the secret-service daemon. For all other platforms, [`internal/config/credentials_keyring_default.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/credentials_keyring_default.go) provides a thin wrapper around `keyring.Get`.

The function `legacyKeyringCredentialValue(key string)` reads values from the OS keyring using the service name `reasonix`:

```go
func legacyKeyringCredentialValue(key string) (string, bool) {
    key = strings.TrimSpace(key)
    if key == "" {
        return "", false
    }
    value, err := keyring.Get(credentialsKeyringService, key)
    return value, err == nil && value != ""
}

```

When resolving credentials via `resolveCredentialForRootGlobalFirst`, the system checks `storedCredentialValueLookup` (set to `legacyKeyringCredentialValue` when in keyring mode). If the key exists, the resolver returns a `CredentialSource` with `Kind: "keyring"`.

## Reading and Writing Credentials Programmatically

### Resolving Credentials

Use `ResolveCredentialForRoot(root, key)` or instantiate a `CredentialResolver` directly to traverse the credential hierarchy:

```go
import "reasonix/internal/config"

func getProviderKey(root, envName string) (string, error) {
    resolver := config.NewCredentialResolverForRoot(root)
    res := resolver.ResolveGlobalFirst(envName)
    if !res.Set {
        return "", fmt.Errorf("environment variable %s not set", envName)
    }
    return res.Value, nil
}

```

This method checks the environment, then infers the source by scanning project `.env`, global Reasonix `.env`, and home `.env` files via `credentialSourceCandidates`.

### Storing Credentials

To write new credentials to the global `$HOME/.env` file, use `SetCredential`:

```go
import "reasonix/internal/config"

func storeOpenAIKey(key string) error {
    // Writes to $HOME/.env and updates the current process environment
    _, err := config.SetCredential("OPENAI_API_KEY", key)
    return err
}

```

This function validates the key format (letters, digits, underscores only), prevents newline injection, and delegates to `StoreCredentialLines`, which updates both the file and the running process environment via `pinCredentialAssignments`.

### Removing Credentials

To delete a stored credential, call `RemoveCredential`:

```go
import "reasonix/internal/config"

func deleteKey(key string) error {
    // Removes from $HOME/.env and adds a "# reasonix-cleared <key>" comment

    return config.RemoveCredential(key)
}

```

This function removes the entry from the credentials file and unsets the corresponding environment variable.

## Migration from Legacy Storage

DeepSeek-Reasonix handles legacy credential files and old keyring entries non-destructively. The resolver only reads from legacy sources when the new global `$HOME/.env` file does not contain a value for the same key. Existing values are never overwritten unless you explicitly call `SetCredential` or `StoreCredentialLines`.

Documentation for migration paths is available in [`docs/MIGRATING.md`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/docs/MIGRATING.md) and [`docs/CONFIG_PATHS.md`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/docs/CONFIG_PATHS.md).

## Summary

- **DeepSeek-Reasonix** manages API credentials through a hierarchical resolution system supporting environment variables, `.env` files, and OS keyring storage.
- The `CredentialResolution` struct tracks values, sources, and shadowed alternatives in [`internal/config/credentials.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/credentials.go).
- Configure storage mode via `REASONIX_CREDENTIALS_STORE` or `~/.reasonix/config.toml`, choosing between `auto`, `keyring`, or `file`.
- Keyring integration uses `github.com/zalando/go-keyring` with platform-specific implementations in [`credentials_keyring_unix.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/credentials_keyring_unix.go) and [`credentials_keyring_default.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/credentials_keyring_default.go).
- Use `SetCredential` to write to `$HOME/.env`, `RemoveCredential` to delete, and `NewCredentialResolverForRoot` to read with full source tracking.

## Frequently Asked Questions

### Where does DeepSeek-Reasonix store API credentials by default?

By default, DeepSeek-Reasonix stores credentials in a global `.env` file located at `$HOME/.env`. This file serves as the primary "Reasonix credentials" store. The system also checks for project-specific `.env` files in the workspace root and environment variables, but writes new credentials to the global location unless configured otherwise.

### How do I enable OS keyring integration in DeepSeek-Reasonix?

Set the environment variable `REASONIX_CREDENTIALS_STORE=keyring` or configure `credentials_store = "keyring"` in `~/.reasonix/config.toml`. When enabled, the system uses the `go-keyring` library to store and retrieve secrets using the service name `reasonix`. The resolver will check the OS keyring when attempting to resolve credential values.

### What is the credential resolution priority order?

The resolver checks sources in this order: first environment variables, then project `.env` files, then the global Reasonix `$HOME/.env` file, then legacy home `.env` files, and finally the OS keyring if configured. The first found value wins, though the system tracks shadowed sources in the `CredentialResolution` struct.

### How do I migrate existing credentials to the new storage system?

Migration is automatic and non-destructive. When resolving credentials, DeepSeek-Reasonix reads from legacy credential files and old keyring entries only if the key does not exist in the new global `$HOME/.env`. To migrate actively, use `config.SetCredential(key, value)` to write values to the new location, which takes precedence over legacy sources.