Skip to content

Feature: Pluggable credential backend interface for self-hosted Mini #96

@rodaddy

Description

@rodaddy

Summary

Jentic Mini uses a Fernet-encrypted SQLite vault for credential storage (src/vault.py). The hosted/VPC edition supports external vault backends (HashiCorp Vault, AWS Secrets Manager, Bitwarden), but Mini has no pluggable interface for self-hosters to bring their own vault.

After reviewing the codebase, the seam is already clean -- get_credential_value() and get_credentials_for_api() in vault.py are the only two functions that touch encrypted values. The broker router never calls vault directly, so swapping the backend is fully contained to one file.

Proposal

Introduce a CredentialBackend protocol/interface:

class CredentialBackend(Protocol):
    async def get_value(self, credential_id: str) -> str | None: ...
    async def get_values_for_api(self, toolkit_id: str, api_id: str) -> list[dict]: ...
    async def store_value(self, credential_id: str, value: str) -> None: ...

The existing Fernet+SQLite implementation becomes FernetBackend (the default). Self-hosters can implement BitwardenBackend, VaultBackend, etc. Backend selection via env var:

JENTIC_CREDENTIAL_BACKEND=fernet  # default
JENTIC_CREDENTIAL_BACKEND=bitwarden
JENTIC_BITWARDEN_URL=https://vaultwarden.local
JENTIC_BITWARDEN_TOKEN=...

Why This Matters for Self-Hosters

Many teams already have a credential vault (Vaultwarden, HashiCorp Vault, 1Password Connect). Requiring credentials to be duplicated into Jentic's SQLite vault creates:

  • Credential sprawl (same secret in two places)
  • Sync drift (vault updated but Jentic not)
  • Operational burden (manual entry via UI/API for each credential)

A pluggable backend lets Jentic pull credentials at execution time from the existing source of truth.

Implementation Notes

  • The OAuthBroker protocol in src/oauth_broker.py already demonstrates the pluggable pattern -- a CredentialBackend would follow the same approach
  • SQLite metadata (credential ID, label, api_id, auth_type) can stay in SQLite regardless of backend -- only the encrypted_value column changes
  • The broker abstraction in src/brokers/ is well-designed and explicitly invites extension

From POC testing by @rodaddy (PAI Infrastructure). We're evaluating Jentic Mini as a credential broker for a multi-user agent fleet backed by Vaultwarden -- the clean seam in vault.py made it clear this is achievable, and we'd love to see it as a first-class feature rather than requiring a fork.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions