Skip to main content

Runtime secret injection with process-level isolation — built for the AI-agent era.

Project description

RSIL — Runtime Secret Isolation Layer

License: MIT Python 3.11+ CI PyPI Platform: POSIX

Runtime secret injection with process-level isolation — built for the AI-agent era.


The Problem

Modern development workflows have introduced a new threat model that existing tools were not designed for:

  1. .env files get committed to Git. Even with .gitignore, accidental pushes happen. Secrets end up in history, forks, and CI logs.

  2. AI coding agents read your entire workspace. Tools like Claude Code, Cursor, and GitHub Copilot run inside your local repository and have read access to every file, including .env.

  3. Environment variables are globally visible. Any process on the same machine can read another process's environment via /proc/<pid>/environ or ps e.

  4. Existing tools don't protect against this. HashiCorp Vault, Doppler, and 1Password solve secret storage, but they still assume your local machine is a trusted environment. That assumption no longer holds.


The Solution

RSIL introduces a new model: secrets never exist on disk in plaintext, and only exist during controlled execution.

# Instead of this:
export STRIPE_KEY=sk_live_abc123
python app.py

# Do this:
rsil run --service payment-api -- python app.py

RSIL:

  • Stores secrets encrypted at ~/.rsil/secrets.enc (Fernet AES-128-CBC + HMAC)
  • Decrypts secrets only at runtime, in memory
  • Spawns your process via fork()/execve() with a minimal, isolated environment
  • Streams stdout/stderr through a redaction layer (secrets never appear in logs)
  • Zeroes all secret data from memory after the process exits
  • Inspects the process tree to block AI agents from triggering secret injection

Features

  • No .env files — secrets are never stored in plaintext on disk
  • Runtime-only injection via POSIX fork()/execve()
  • Minimal environment — child process receives only what it needs (PATH, HOME, and your secrets)
  • Process-level caller inspection — deny AI agent processes by name
  • Stdout/stderr redaction — secret values are replaced with ***REDACTED*** in all output
  • Automatic memory cleanup on exit (overwrite + GC)
  • Encrypted local store with Fernet (AES-128-CBC + HMAC-SHA256)
  • Audit log at ~/.rsil/audit.log (JSON-lines)
  • Policy engine for fine-grained process-level access control (v0.4)

How It Compares

Feature Vault Doppler direnv RSIL
Central secret storage
Runtime injection
Local dev focus ⚠️
No network dependency
AI agent protection
Process-level isolation
Output redaction
No plaintext on disk

The last three rows are RSIL's moat.


Installation

pip install rsil

Or with uv:

uv add rsil

Then initialize RSIL (creates ~/.rsil/ and generates your master key):

rsil init

Quick Start

# 1. Initialize (one-time setup)
rsil init

# 2. Add secrets
rsil add STRIPE_KEY=sk_live_yourkey --service payment-api
rsil add DATABASE_URL=postgres://localhost/mydb --service payment-api

# 3. Verify (shows keys, never values)
rsil list --service payment-api

# 4. Run your app
rsil run --service payment-api -- python app.py

# With uvicorn
rsil run --service payment-api -- uvicorn main:app --reload

Your application reads secrets normally via os.environ:

import os
stripe_key = os.getenv("STRIPE_KEY")  # injected at runtime by RSIL

No .env file. No export. No risk.


CLI Reference

rsil init

Initialize RSIL. Creates ~/.rsil/ and generates master.key.

rsil init

rsil add

Add or update a secret.

rsil add KEY=value --service SERVICE_NAME
Flag Description
--service Service name to scope the secret to (required)

rsil list

List secret keys for a service. Never shows values.

rsil list [--service SERVICE_NAME]
Flag Description
--service Filter by service name (optional — shows all if omitted)

rsil delete

Delete a secret.

rsil delete KEY --service SERVICE_NAME

rsil run

Run a command with secrets injected.

rsil run [--service SERVICE_NAME] [--no-redact] -- COMMAND [ARGS...]
Flag Description
--service Service name to load secrets from
--no-redact Disable output redaction (use only for debugging)

The -- separator is required to separate RSIL flags from the command.


Architecture

rsil run --service payment-api -- python app.py
         |
         v
  cli/commands/run.py
         |
         v
  core/executor.py :: Executor.run()
         |
         +--[1] security/process_guard.py  check parent process
         |       if parent in AI_BLOCKLIST → deny
         |
         +--[2] policy/engine.py           evaluate access rules
         |       (stub in v0.1, active in v0.4)
         |
         +--[3] secrets/manager.py         decrypt ~/.rsil/secrets.enc
         |       → {"STRIPE_KEY": "sk_live_..."}
         |
         +--[4] core/env_builder.py        build minimal env
         |       → {"STRIPE_KEY": "...", "PATH": "...", "HOME": "..."}
         |       NEVER copies os.environ
         |
         +--[5] core/process.py            os.fork() + os.execve()
         |       child: disable core dumps → exec
         |       parent: pipe stdout/stderr through Redactor
         |
         +--[6] core/cleanup.py            destroy() — zero secrets, gc.collect()
         |
         +--[7] security/audit.py          write JSON event to audit.log

Key modules

Module Responsibility
rsil/cli/ typer-based CLI, one file per command
rsil/core/executor.py Lifecycle orchestration
rsil/core/process.py POSIX fork/execve, pipe-based I/O
rsil/core/env_builder.py Minimal environment construction
rsil/secrets/ Encrypted store, Fernet crypto, SecretManager
rsil/security/process_guard.py AI agent detection via psutil
rsil/security/redact.py Stdout/stderr secret redaction
rsil/policy/ YAML-based access control rules (v0.4)

Security Model

What RSIL protects against:

  • Accidental .env file commits to Git
  • AI coding agents reading .env or os.environ during a session
  • Secrets leaking into stdout/stderr logs
  • Secrets persisting in the parent process environment after execution
  • Core dump files containing secret values

What RSIL does NOT protect against:

  • A root-level attacker on the same machine
  • Memory scraping by a privileged process
  • Secrets that your own application logs explicitly
  • Network-level interception (RSIL is a local tool, not a network proxy)
  • Compromised Python interpreter or standard library

RSIL is a local runtime isolation layer, not a remote secrets manager. Use it alongside (not instead of) proper secret management for production deployments.


Roadmap

See docs/roadmap.md for the full week-by-week plan.

Version Goal
v0.1 CLI + encrypted store + basic fork()/execve() execution
v0.2 Process guard + minimal env + integration tests
v0.3 Pipe-based secret injection (experimental)
v0.4 Policy engine + FastAPI example

Contributing

See CONTRIBUTING.md.


License

MIT — see LICENSE. Copyright Sentivs 2026.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rsil-0.1.0.tar.gz (41.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rsil-0.1.0-py3-none-any.whl (28.8 kB view details)

Uploaded Python 3

File details

Details for the file rsil-0.1.0.tar.gz.

File metadata

  • Download URL: rsil-0.1.0.tar.gz
  • Upload date:
  • Size: 41.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rsil-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5258b711a4876b042e6afb41a98c26e06c9f05cf95888f94b000a0c83be277bc
MD5 64ef1de0376860becc380d48cee89263
BLAKE2b-256 844d5384ed92029372aa179b5aeb87900cc2f5e58fae861cca6e00e966f77fef

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsil-0.1.0.tar.gz:

Publisher: publish.yml on Sentivs-co/rsil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rsil-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: rsil-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rsil-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a5c452e6d7a9df9022e72bb520c02ec43fbec25632f8dcc66f23d5a47eff1463
MD5 f76214165302a9a22ff865befaa900c2
BLAKE2b-256 c17d4e25de704c1294bd003ab64482deb362121cbf192ef10ec3c7e6b0f421f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsil-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Sentivs-co/rsil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page