Skip to content

onetimesecret/ots5

Repository files navigation

OneTimeSecret Python3 Community Edition

A modern Python3 implementation of OneTimeSecret, providing secure one-time message sharing with automatic link expiration after viewing. Built following Python community standards and conventions for maintainability, security, and extensibility.

Features

  • One-time viewing: Secrets automatically expire after first access
  • Time-based expiration: Optional TTL for unviewed secrets
  • Passphrase protection: Optional encryption layer for additional security
  • RESTful API: Compatible with OneTimeSecret v2 specification
  • Redis backend: Fast and reliable storage with automatic expiration
  • Type safety: Full type hints throughout the codebase
  • Comprehensive testing: Unit and integration tests with >80% coverage
  • Docker support: Easy deployment with Docker and Docker Compose

Technical Specifications

  • Python: 3.10+
  • Framework: FastAPI for REST API
  • Database: Redis (primary storage for secrets)
  • Encryption: Fernet symmetric encryption with optional passphrase-based key derivation
  • API: RESTful JSON API maintaining compatibility with OneTimeSecret v2 specification

Quick Start

Using Docker Compose (Recommended)

  1. Clone the repository:
git clone https://github.com/onetimesecret/onetimesecret-python
cd onetimesecret-python
  1. Generate a secure secret key:
python -c "import secrets; print(secrets.token_urlsafe(32))"
  1. Create .env file:
cp .env.example .env
# Edit .env and set OTS_SECRET_KEY to your generated key
  1. Start the services:
docker-compose up -d
  1. Access the API:

Manual Installation

Prerequisites

  • Python 3.10 or higher
  • Redis server
  • Virtual environment tool (venv/virtualenv)

Setup Steps

  1. Clone and navigate to the repository:
git clone https://github.com/onetimesecret/onetimesecret-python
cd onetimesecret-python
  1. Create and activate virtual environment:
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install dependencies:
pip install -r requirements/base.txt
# For development:
# pip install -r requirements/dev.txt
  1. Generate a secure secret key:
python -c "import secrets; print(secrets.token_urlsafe(32))"
  1. Configure environment:
cp .env.example .env
# Edit .env with your configuration, especially OTS_SECRET_KEY
  1. Start Redis (if not already running):
redis-server
  1. Start the development server:
uvicorn onetimesecret.main:app --reload

The API will be available at http://localhost:8000

Configuration

Configuration is managed through environment variables with the OTS_ prefix. See .env.example for all available options.

Key Configuration Options

Variable Default Description
OTS_REDIS_URL redis://localhost:6379/0 Redis connection URL
OTS_SECRET_KEY Required Application secret key (generate a secure random key)
OTS_SSL_ENABLED false Enable SSL/TLS enforcement
OTS_AUTH_REQUIRED false Require authentication for API access
OTS_PASSPHRASE_REQUIRED false Require passphrase for all secrets
OTS_MAX_SECRET_SIZE 1048576 Maximum secret size in bytes (1MB)
OTS_DEFAULT_TTL 604800 Default TTL in seconds (7 days)
OTS_MAX_TTL 2592000 Maximum TTL in seconds (30 days)

API Usage

Create a Secret

curl -X POST http://localhost:8000/api/v2/secrets \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "This is my secret message",
    "ttl": 3600
  }'

Response:

{
  "secret_key": "abc123def456",
  "metadata_key": "abc123def456:metadata",
  "ttl": 3600,
  "created_at": "2023-01-01T00:00:00"
}

Create a Passphrase-Protected Secret

curl -X POST http://localhost:8000/api/v2/secrets \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "Protected secret",
    "passphrase": "my_secure_password",
    "ttl": 7200
  }'

Retrieve a Secret

Using GET:

curl http://localhost:8000/api/v2/secrets/abc123def456

Using POST with passphrase:

curl -X POST http://localhost:8000/api/v2/secrets/abc123def456 \
  -H "Content-Type: application/json" \
  -d '{"passphrase": "my_secure_password"}'

Response:

{
  "secret": "This is my secret message",
  "created_at": "2023-01-01T00:00:00"
}

Get Secret Metadata

curl http://localhost:8000/api/v2/secrets/abc123def456/metadata

Response:

{
  "secret_key": "abc123def456",
  "created_at": "2023-01-01T00:00:00",
  "ttl": 3600,
  "viewed": false,
  "has_passphrase": true
}

Delete a Secret

curl -X DELETE http://localhost:8000/api/v2/secrets/abc123def456

Development

Running Tests

# Install development dependencies
pip install -r requirements/dev.txt

# Run all tests
pytest

# Run with coverage
pytest --cov=onetimesecret --cov-report=html

# Run only unit tests
pytest tests/unit -m unit

# Run only integration tests
pytest tests/integration -m integration

Code Quality

# Format code with Black
black src/ tests/

# Lint with Ruff
ruff check src/ tests/

# Type checking with mypy
mypy src/

Project Structure

onetimesecret/
├── src/
│   └── onetimesecret/
│       ├── __init__.py
│       ├── main.py              # FastAPI application entry point
│       ├── api/
│       │   ├── routes.py        # API endpoints
│       │   └── validators.py    # Input validation
│       ├── core/
│       │   ├── config.py        # Configuration management
│       │   └── exceptions.py    # Custom exceptions
│       ├── models/
│       │   └── secret.py        # Pydantic models
│       ├── services/
│       │   ├── redis_client.py  # Redis storage client
│       │   └── secret_service.py # Business logic
│       └── utils/
│           └── crypto.py        # Cryptographic utilities
├── tests/
│   ├── unit/                    # Unit tests
│   ├── integration/             # Integration tests
│   └── conftest.py              # Pytest fixtures
├── requirements/
│   ├── base.txt                 # Production dependencies
│   ├── dev.txt                  # Development dependencies
│   └── prod.txt                 # Production + deployment tools
├── pyproject.toml               # Project metadata and tool config
├── setup.cfg                    # Additional tool configuration
├── Dockerfile                   # Container image definition
├── docker-compose.yml           # Local development stack
└── README.md                    # This file

Security Considerations

Encryption

  • All secrets are encrypted using Fernet (symmetric encryption)
  • Optional passphrase protection adds an additional encryption layer using PBKDF2
  • Secrets are never stored in plaintext
  • Cryptographically secure random key generation

Best Practices

  1. Generate a Strong Secret Key: Use the provided command to generate a cryptographically secure key

    python -c "import secrets; print(secrets.token_urlsafe(32))"
  2. Use Environment Variables: Never commit secrets to version control

  3. Enable SSL/TLS in Production: Set OTS_SSL_ENABLED=true and use HTTPS

  4. Set Appropriate TTLs: Configure reasonable default and maximum TTL values

  5. Monitor Access: Implement logging and monitoring for production deployments

  6. Regular Updates: Keep dependencies updated for security patches

Production Deployment

Docker

Build and run the container:

docker build -t onetimesecret:latest .
docker run -d \
  -p 8000:8000 \
  -e OTS_REDIS_URL=redis://your-redis:6379/0 \
  -e OTS_SECRET_KEY=your-secure-key \
  -e OTS_SSL_ENABLED=true \
  onetimesecret:latest

Using Gunicorn

For production deployments with multiple workers:

pip install -r requirements/prod.txt
gunicorn onetimesecret.main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000

API Documentation

Once the server is running, interactive API documentation is available at:

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please ensure:

  • All tests pass
  • Code follows PEP 8 style guidelines
  • Type hints are included
  • Documentation is updated
  • Test coverage remains >80%

Support

For issues and questions:

Acknowledgments

Based on the original OneTimeSecret project: https://github.com/onetimesecret/onetimesecret

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors