# NanaSQLite-Server

[English](#english) | [日本語](#日本語)

---

## English

A secure, high-performance, QUIC-based RPC server for [NanaSQLite](https://github.com/disnana/NanaSQLite/).

### ⚠️ Security Warning
The security of this server depends on the method structure of the `NanaSQLite` class. While we use a dynamic protection mechanism, **updates to NanaSQLite may introduce new methods that could potentially bypass current security restrictions.** Always review the `FORBIDDEN_METHODS` in `server.py` when updating the underlying `nanasqlite` library.

**Current Supported NanaSQLite Version:** v1.3.3+

### Features
- **QUIC Protocol**: Built on top of HTTP/3 technology for low latency and high reliability.
- **Ed25519 Passkey Authentication**: Secure challenge-response authentication.
- **Post-Quantum Cryptography (PQC)**: Optional [liboqs-python](https://github.com/open-quantum-safe/liboqs-python)-based PQC authentication (Dilithium, Falcon, SPHINCS+, etc.). See [docs/pqc.md](docs/pqc.md).
- **Performance**: Optimized with `ormsgpack` for ultra-fast message serialization.
- **Concurrency & Safety**: Thread-safe operations using `RLock` and optimized with `WAL` mode.
- **Reliability**: Enhanced task management for Python 3.13+ compatibility.
- **Role-Based Access Control (RBAC)**: Manage allowed/forbidden methods per account.
- **Multi-DB Support**: Securely access multiple databases within a designated directory.
- **Cross-Platform**: Fully optimized for Windows, Linux, and macOS.

### Quick Start
```bash
pip install nanasqlite-server
# Generate certificate and keys
nanasqlite-cert-gen
nanasqlite-key-gen
# Alternative if the commands above are not on PATH
python -m nanasqlite_server.cert_gen
python -m nanasqlite_server.key_gen
# Start the server
nanasqlite-server
```

For post-quantum cryptography (PQC) authentication:
```bash
pip install "nanasqlite-server[pqc]"
# ML-DSA-65 (equivalent to Dilithium3, NIST FIPS 204)
nanasqlite-pqc-key-gen --algorithm ML-DSA-65
```
See [docs/pqc.md](docs/pqc.md) for full PQC setup instructions.

### Multi-Database & RBAC Configuration
Configure accounts and database access in `accounts.json`:

```json
{
    "db_dir": "./data",
    "accounts": [
        {
            "name": "admin",
            "public_key": "ssh-ed25519 ...",
            "allowed_methods": null,
            "allowed_dbs": ["main.sqlite", "logs.sqlite"]
        },
        {
            "name": "readonly_user",
            "public_key": "ssh-ed25519 ...",
            "allowed_methods": ["get_item_async", "list_tables"],
            "allowed_dbs": ["main.sqlite"]
        },
        {
            "name": "viewer",
            "public_key": "ssh-ed25519 ...",
            "read_only": true,
            "allowed_dbs": {
                "logs.sqlite": null,
                "data.sqlite": ["public_info", "stats"]
            }
        }
    ]
}
```
*Note: `db_dir` is the base directory. Remote clients can only access databases explicitly listed in their `allowed_dbs`. Use `"read_only": true` to block all write operations. Pass `allowed_dbs` as a dict to restrict access to specific tables per database.*

See [docs/rbac.md](docs/rbac.md) for full RBAC documentation.

### Customizing Allowed Methods
When launching the server programmatically, you can customize which methods are allowed or forbidden:

```python
import asyncio
from nanasqlite_server.server import main

async def start_server():
    # Allow 'close' explicitly and forbid '__setitem__'
    await main(
        allowed_methods={"close"},
        forbidden_methods={"__setitem__"}
    )

if __name__ == "__main__":
    asyncio.run(start_server())
```

### Client Usage Example
```python
import asyncio
from nanasqlite_server.client import RemoteNanaSQLite

async def main():
    # Specify connection info
    db = RemoteNanaSQLite(host="127.0.0.1", port=4433)
    
    # Connect and authenticate (requires nana_private.pem)
    await db.connect()
    
    # Perform data operations (async methods)
    await db.set_item_async("key", "value")
    val = await db.get_item_async("key")
    print(f"Read back: {val}")
    
    # Close connection
    await db.close()

if __name__ == "__main__":
    asyncio.run(main())
```
*Note: If no database is specified by the client and the account has no `allowed_dbs` restriction, the database specified by the server's `--db` option (default: `server_db.sqlite`) will be used.*

### Concurrency & Locking Design
NanaSQLite-Server uses a high-concurrency model optimized for safety:
- **Threadpool Offloading**: All database operations are offloaded to a shared thread pool (default 10 workers) to prevent blocking the async event loop.
- **Per-DB Locking**: Each database instance is protected by a thread-safe `RLock`. Multiple readers/writers are safely queued.
- **WAL Mode**: Databases are initialized in `WAL` (Write-Ahead Logging) mode, allowing concurrent reads even during write operations.

---

## 日本語

[NanaSQLite](https://github.com/disnana/NanaSQLite/) のためのセキュアで高速な QUIC ベースの RPC サーバーです。

### ⚠️ セキュリティに関する重要な警告
このサーバーのセキュリティは `NanaSQLite` クラスのメソッド構造に依存しています。動的な保護メカニズムを採用していますが、**NanaSQLite のアップデートにより、現在の制限を回避できる新しいメソッドが導入される可能性があります。** `nanasqlite` ライブラリを更新する際は、必ず `server.py` 内の `FORBIDDEN_METHODS` を確認し、必要に応じて更新してください。

**現在対応している NanaSQLite バージョン:** v1.3.2+

### 特徴
- **QUIC プロトコル**: HTTP/3 テクノロジーをベースにした低遅延で信頼性の高い通信。
- **Ed25519 パスキー認証**: チャレンジ/レスポンス方式によるセキュアな認証。
- **耐量子暗号 (PQC)**: [liboqs-python](https://github.com/open-quantum-safe/liboqs-python) によるオプションの PQC 認証 (Dilithium, Falcon, SPHINCS+ など)。詳細は [docs/pqc.md](docs/pqc.md) を参照。
- **パフォーマンス**: `ormsgpack` による超高速なメッセージシリアライズ。
- **並行性と安全性**: `RLock` によるスレッドセーフな操作と `WAL` モードによる最適化。
- **信頼性**: Python 3.13+ 対応のタスク管理強化により、安定した長時間稼働を実現。
- **ロールベースアクセス制御 (RBAC)**: アカウントごとの許可/禁止メソッドの管理。
- **マルチDB対応**: 指定したディレクトリ内の複数のDBへ安全にアクセス。
- **マルチプラットフォーム**: Windows, Linux, macOS に完全対応。

### クイックスタート
```bash
pip install nanasqlite-server
# 証明書と鍵の生成
nanasqlite-cert-gen
nanasqlite-key-gen
# 証明書と鍵の生成（PATHが通っていない場合）
python -m nanasqlite_server.cert_gen
python -m nanasqlite_server.key_gen
# サーバーの起動
nanasqlite-server
```

耐量子暗号 (PQC) を使用する場合:
```bash
pip install "nanasqlite-server[pqc]"
# 基本的なML-DSA-65（Dilithium3相当）
nanasqlite-pqc-key-gen --algorithm ML-DSA-65
```
詳細は [docs/pqc.md](docs/pqc.md) を参照してください。

### マルチDB & RBAC 設定
`accounts.json` でアカウントとアクセス可能なDBを構成します。

```json
{
    "db_dir": "./data",
    "accounts": [
        {
            "name": "admin",
            "public_key": "ssh-ed25519 ...",
            "allowed_methods": null,
            "allowed_dbs": ["main.sqlite", "logs.sqlite"]
        },
        {
            "name": "readonly_user",
            "public_key": "ssh-ed25519 ...",
            "allowed_methods": ["get_item_async", "list_tables"],
            "allowed_dbs": ["main.sqlite"]
        }
    ]
}
```
*注: `db_dir` はベースディレクトリです。クライアントは `allowed_dbs` に明記されたDBにのみアクセス可能です。*

### 許可メソッドのカスタマイズ
プログラムからサーバーを起動する場合、許可または禁止するメソッドをカスタマイズできます。

```python
import asyncio
from nanasqlite_server.server import main

async def start_server():
    # 'close' を明示的に許可し、'__setitem__' を禁止する例
    await main(
        allowed_methods={"close"},
        forbidden_methods={"__setitem__"}
    )

if __name__ == "__main__":
    asyncio.run(start_server())
```

### クライアントの使用例
```python
import asyncio
from nanasqlite_server.client import RemoteNanaSQLite

async def main():
    # 接続情報の指定
    db = RemoteNanaSQLite(host="127.0.0.1", port=4433)
    
    # 接続と認証（秘密鍵 nana_private.pem が必要）
    await db.connect()
    
    # 非同期メソッドによるデータ操作
    await db.set_item_async("key", "value")
    val = await db.get_item_async("key")
    print(f"Read back: {val}")
    
    # 終了
    await db.close()

if __name__ == "__main__":
    asyncio.run(main())
```

### 並行処理とロック設計
NanaSQLite-Server は安全性を最優先した並行処理モデルを採用しています。
- **スレッドプール・オフロード**: すべての DB 操作は共有スレッドプール（デフォルト10ワーカー）にオフロードされ、非同期イベントループをブロックしません。
- **DB単位のロック**: 各 DB インスタンスは `RLock` で保護されており、同一 DB への同時アクセスは適切にキューイングされ安全に実行されます。
- **WAL モード**: DB は `WAL` (Write-Ahead Logging) モードで動作し、書き込み操作中であっても読み取りを妨げない設計になっています。

## License
MIT License
