Metadata-Version: 2.4
Name: panda-crypto-py
Version: 0.2.5
Summary: Private And Secure Data Access - Field-level encryption SDK for Python
Author-email: Bidang Persandian dan Keamanan Informasi - Dinas Komunikasi dan Informatika Provinsi Jawa Timur <csirt@jatimprov.go.id>
Maintainer-email: Bidang Persandian dan Keamanan Informasi - Dinas Komunikasi dan Informatika Provinsi Jawa Timur <csirt@jatimprov.go.id>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/jatimprovcsirt/panda-crypto-py
Project-URL: Documentation, https://csirt.jatimprov.go.id/panda/docs
Project-URL: Repository, https://github.com/jatimprovcsirt/panda-crypto-py
Project-URL: Issues, https://github.com/jatimprovcsirt/panda-crypto-py/issues
Keywords: encryption,security,gdpr,pdp,privacy,aes-256-gcm
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: cryptography>=41.0.0
Requires-Dist: click>=8.0.0
Provides-Extra: django
Requires-Dist: django>=3.2; extra == "django"
Provides-Extra: flask
Requires-Dist: flask>=2.0; extra == "flask"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.68.0; extra == "fastapi"
Requires-Dist: pydantic>=2.0.0; extra == "fastapi"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Provides-Extra: all
Requires-Dist: panda-crypto-py[dev,django,fastapi,flask]; extra == "all"
Dynamic: license-file

# PANDA Python SDK

Private And Secure Data Access — Field-level encryption SDK for Python applications.

## Overview

PANDA (Private And Secure Data Access) is a cross-language SDK for field-level encryption and masking of sensitive personal data. The Python implementation provides the same features as the PHP, Node.js, and Go versions:

- **AES-256-GCM encryption** with envelope wire format
- **Masking-by-default** decrypted values
- **Blind indexing** for searchable encrypted fields
- **Multiple key providers**: Local (.env), HashiCorp Vault, Infisical
- **CLI tool** for initialization and key management
- **Framework integrations**: Django, Flask, FastAPI

## Installation

```bash
pip install panda-crypto-py
```

## Quick Start

### 1. Initialize PANDA

```bash
panda init --token panda_demo_76d08573d453cdbdb4bf5704d13f8f54d57cd3c47c9b4be2
```

The wizard will guide you through:
- Selecting a key provider (Local, Vault, or Infisical)
- Configuring your provider
- Generating your first encryption key

### 2. Use in Your Code

```python
from panda.crypto import FieldCipher, LocalKeyProvider

# Create cipher with local keys
key_provider = LocalKeyProvider()
cipher = FieldCipher(key_provider)

# Encrypt data
envelope = cipher.encrypt("3201012501990001", kid="nik-key")

# Decrypt (returns masked value by default)
masked = cipher.decrypt(envelope)
print(masked)  # "32************01"

# Decrypt raw (audited operation)
raw = cipher.decrypt_raw(envelope)
print(raw)  # "3201012501990001"
```

## Key Providers

### Local (Environment Variables)

```python
from panda.crypto import LocalKeyProvider

# Keys are read from PANDA_KEY_<KID> environment variables
# PANDA_KEY_NIK_KEY=<base64-encoded-32-byte-key>
key_provider = LocalKeyProvider()
```

### HashiCorp Vault

```python
from panda.crypto import VaultKeyProvider

key_provider = VaultKeyProvider(
    vault_url="http://localhost:8200",
    vault_token="your-token",
    mount_path="secret"
)
```

### Infisical

```python
from panda.crypto import InfisicalKeyProvider

key_provider = InfisicalKeyProvider(
    site_url="https://app.infisical.com",
    client_id="your-client-id",
    client_secret="your-client-secret",
    project_id="your-project-id",
    environment="dev"
)
```

## Masking

```python
from panda.masking import Masker

# Default: keep 2 leading, 2 trailing characters
masked = Masker.mask("3201012501990001")
# "32************01"

# Custom masking
masked = Masker.mask(
    "3201012501990001",
    keep_leading=3,
    keep_trailing=1,
    mask_char="*"
)
# "320*************1"
```

## Blind Indexing

```python
from panda.blind_index import BlindIndexer

# Generate blind index for searchable encryption
index = BlindIndexer.generate(
    plaintext="3201012501990001",
    key="blind-index-key",
    normalization="digits"  # or "lowercase", "trim", "raw"
)
```

## Framework Integration

### Django

```python
# settings.py
INSTALLED_APPS = [
    ...
    'panda.integrations.django',
]

PANDA = {
    'KEY_PROVIDER_DRIVER': 'local',
    'DEFAULT_KID': 'default-key',
}

# models.py
from panda.integrations.django.fields import EncryptedField
from django.db import models

class Citizen(models.Model):
    nik = EncryptedField(kid='nik-key')
    name = models.CharField(max_length=200)
```

### Flask

```python
from flask import Flask
from panda.integrations.flask import PandaFlask

app = Flask(__name__)
panda = PandaFlask(app)

@app.route('/encrypt')
def encrypt():
    envelope = panda.cipher.encrypt("sensitive data", kid="my-key")
    return envelope.to_json()
```

### FastAPI

```python
from fastapi import FastAPI
from panda.integrations.fastapi import PandaFastAPI

app = FastAPI()
panda = PandaFastAPI(app)

@app.post("/encrypt")
def encrypt_endpoint(data: str):
    envelope = panda.cipher.encrypt(data, kid="my-key")
    return envelope.to_dict()
```

## CLI Commands

### Mode Non-Interaktif (Flags untuk CI/CD)

Semua perintah CLI dapat digunakan dalam mode non-interaktif dengan menggunakan flag. Ini sangat berguna untuk:

- **CI/CD pipelines** - Otomatisasi tanpa interaksi pengguna
- **Docker containers** - Inisialisasi otomatis saat container start
- **Infrastructure as Code** - Integrasi dengan Terraform, Ansible, dll
- **Automated testing** - Setup dan teardown otomatis

#### Perintah Init - Mode Non-Interaktif

```bash
# Quick init dengan Local provider (mode tercepat)
panda init --token <token> --kid default-key

# Init tanpa generate kunci pertama (untuk automation lanjutan)
panda init --token <token> --reinit

# Init dengan environment variable
export PANDA_ACCESS_TOKEN=<token>
panda init
```

**Flag `init` yang tersedia:**

| Flag | Default | Deskripsi |
|------|---------|-----------|
| `--token <value>` | - | PANDA access token (atau set `PANDA_ACCESS_TOKEN` env) |
| `--reinit` | `false` | Force re-initialization meskipun sudah ada konfigurasi |

#### Perintah Generate - Mode Non-Interaktif

```bash
# Generate kunci dengan KID langsung (non-interactive)
panda generate my-new-key

# Generate dengan description
panda generate nik-key --description "Key for NIK encryption"
```

**Flag `generate` yang tersedia:**

| Flag | Default | Deskripsi |
|------|---------|-----------|
| `--description <text>` | - | Deskripsi untuk kunci |

#### Perintah Deinit - Mode Non-Interaktif

```bash
# Hapus konfigurasi tanpa prompt
panda deinit --force
```

**Flag `deinit` yang tersedia:**

| Flag | Default | Deskripsi |
|------|---------|-----------|
| `--force` | `false` | Skip konfirmasi prompt |

#### Tabel Lengkap Perintah CLI

```bash
# Initialize PANDA
panda init --token <your-token>

# Generate a new key
panda generate my-key

# Check status
panda status

# View configuration
panda config

# Remove PANDA from project
panda deinit --force
```

| Perintah | Memerlukan Token | Mode Non-Interaktif | Deskripsi |
|---|---|---:|---|
| `panda init --token <token>` | ✅ Ya | ✅ (default) | Inisialisasi PANDA |
| `panda generate <kid>` | ❌ Tidak | ✅ (default non-interactive) | Generate kunci tambahan |
| `panda status` | ❌ Tidak | ✅ (default non-interactive) | Tampilkan status konfigurasi |
| `panda config` | ❌ Tidak | ✅ (default non-interactive) | Tampilkan detail konfigurasi lengkap |
| `panda deinit` | ❌ Tidak | ✅ `--force` | Hapus konfigurasi PANDA |

## Envelope Format

Encrypted fields use a standardized JSON envelope:

```json
{
  "v": 1,
  "alg": "aes-256-gcm",
  "kid": "key-identifier",
  "nonce": "<base64 12-byte IV>",
  "ciphertext": "<base64 ciphertext + 16-byte auth tag>"
}
```

## Documentation

- [Full Documentation](docs/)
- [Envelope Format Spec](spec/envelope-format.md)
- [CLI Reference](docs/cli.md)
- [Framework Integrations](docs/integrations.md)

## License

Apache License 2.0 — see `LICENSE` for the full text and `NOTICE` for
attribution.

Previously MIT. Apache-2.0 is equally permissive and adds an express patent
grant and a trademark clause, which MIT is silent on — it matters here because
this is cryptographic software that other agencies and vendors are expected to
embed in their own systems.

## Support

For issues and questions:
- GitHub Issues: https://github.com/jatimprovcsirt/panda-crypto-py/issues
- Documentation: https://csirt.jatimprov.go.id/panda/docs
