Metadata-Version: 2.4
Name: spectra-auth
Version: 1.0.0
Summary: API key management and authentication middleware for Spectra analytics
Project-URL: Homepage, https://spectrajs.com
Project-URL: Repository, https://github.com/photonhq/spectra
Project-URL: Bug Tracker, https://github.com/photonhq/spectra/issues
License: MIT License
        
        Copyright (c) 2026 Photon
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: analytics,api-key,authentication,fastapi,middleware,starlette
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: pymongo>=4.6.0
Requires-Dist: starlette>=0.27.0
Provides-Extra: dev
Requires-Dist: fastapi>=0.100.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.100.0; extra == 'fastapi'
Description-Content-Type: text/markdown

# spectra-auth

API key management and authentication middleware for [Spectra](https://spectrajs.com) analytics.

## Installation

```bash
pip install spectra-auth
```

For FastAPI projects, install with the optional FastAPI dependency:

```bash
pip install "spectra-auth[fastapi]"
```

## Configuration

### Explicit (recommended)

Call `configure()` once at application startup before using any other functions:

```python
from spectra_auth import configure

configure(
    mongodb_uri="mongodb+srv://user:pass@cluster.mongodb.net/",
    mongodb_database="spectra",
)
```

### Environment variables (fallback)

If `configure()` is not called, the library reads from the environment:

| Variable           | Default                        | Description              |
|--------------------|--------------------------------|--------------------------|
| `MONGODB_URI`      | `mongodb://localhost:27017`    | MongoDB connection string |
| `MONGODB_DATABASE` | `spectra`                      | Database name             |

Copy `.env.example` to `.env` and fill in your values.

## Usage

### Starlette / FastAPI middleware

Add `AuthMiddleware` to enforce authentication on all routes:

```python
from fastapi import FastAPI
from spectra_auth import configure, AuthMiddleware

configure(mongodb_uri="...", mongodb_database="spectra")

app = FastAPI()
app.add_middleware(AuthMiddleware)
```

**Authentication flow per request:**

1. `account_id` is always required — passed via the `X-Account-ID` header or an `account_id` field in the JSON body.
2. If the request `Origin` / `Referer` matches an allowed origin for that account, the request passes through without an API key.
3. Otherwise, a valid API key must be provided via:
   - `Authorization: Bearer <key>` header _(standard)_
   - `api_key` field in the JSON body _(sendBeacon fallback)_

The `/health` path is always unauthenticated.

### FastAPI route dependency

Use `require_api_key` as a route-level dependency when you need per-route enforcement instead of middleware:

```python
from fastapi import Depends, FastAPI
from spectra_auth import require_api_key

app = FastAPI()

@app.get("/protected", dependencies=[Depends(require_api_key)])
async def protected_route():
    return {"message": "authenticated"}
```

### API key management

```python
from spectra_auth import create_api_key, delete_api_key, verify_key

# Create a new key (returns the raw key — store it securely, it is never stored in plain text)
raw_key = create_api_key(account_id="acct_123", label="Production")

# Verify a key
is_valid = verify_key(raw_key, account_id="acct_123")

# Delete a key
deleted = delete_api_key(raw_key)
```

### Allowed origins

Allowed origins let browser clients send requests without an API key, identified by their `Origin` header:

```python
from spectra_auth import add_allowed_origin, remove_allowed_origin, get_allowed_origins

add_allowed_origin("acct_123", "https://yourapp.com")

origins = get_allowed_origins("acct_123")
# ["https://yourapp.com"]

remove_allowed_origin("acct_123", "https://yourapp.com")
```

## MongoDB schema

`spectra-auth` expects two collections in your database:

| Collection        | Key fields                                     |
|-------------------|------------------------------------------------|
| `api_keys`        | `account_id`, `key_hash`, `created_at`, `label` |
| `allowed_origins` | `account_id`, `origins` (array)                |

Indexes are created automatically on first use.

## License

MIT
