Metadata-Version: 2.5
Name: laidline
Version: 1.0.0
Summary: Marking kit for generative AI providers: C2PA signing with your KMS, open watermarks, evidence log, free detect.
Project-URL: Homepage, https://laidline.com
Project-URL: Documentation, https://laidline.com/docs/quickstart
Project-URL: Changelog, https://laidline.com/docs/changelog
Author: Laidline LLC
License-Expression: LicenseRef-Laidline-Source-Available
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES
Keywords: ai-act,audioseal,c2pa,content-credentials,provenance,synthid,trustmark,watermark
Classifier: Development Status :: 5 - Production/Stable
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.12
Requires-Dist: cryptography>=43
Requires-Dist: httpx<1,>=0.27
Requires-Dist: jinja2>=3.1
Requires-Dist: pydantic-settings>=2
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6
Requires-Dist: rfc3161-client>=1.0.9
Requires-Dist: rfc8785>=0.1.4
Requires-Dist: typer>=0.12
Provides-Extra: all
Requires-Dist: audioseal<0.3,>=0.2.0; extra == 'all'
Requires-Dist: av<19,>=18.1; extra == 'all'
Requires-Dist: boto3<2; extra == 'all'
Requires-Dist: c2pa-python<0.38,>=0.37.10; extra == 'all'
Requires-Dist: cbor2<6,>=5.6; extra == 'all'
Requires-Dist: einops; extra == 'all'
Requires-Dist: fastapi<1,>=0.115; extra == 'all'
Requires-Dist: google-cloud-storage<4,>=3.15; extra == 'all'
Requires-Dist: httpx; extra == 'all'
Requires-Dist: hvac<3; extra == 'all'
Requires-Dist: numpy>=1.26; extra == 'all'
Requires-Dist: omegaconf; extra == 'all'
Requires-Dist: onnxruntime==1.24.4; extra == 'all'
Requires-Dist: pillow>=10; extra == 'all'
Requires-Dist: prometheus-client<1; extra == 'all'
Requires-Dist: psycopg[binary,pool]>=3.2; extra == 'all'
Requires-Dist: python-jsonpath<3,>=2.2.1; extra == 'all'
Requires-Dist: python-multipart<1; extra == 'all'
Requires-Dist: torch>=2.5; extra == 'all'
Requires-Dist: torchvision; extra == 'all'
Requires-Dist: transformers>=4.46; extra == 'all'
Requires-Dist: trustmark<0.10,>=0.9.2; extra == 'all'
Requires-Dist: uvicorn[standard]<1; extra == 'all'
Requires-Dist: watchfiles<2; extra == 'all'
Provides-Extra: audio
Requires-Dist: audioseal<0.3,>=0.2.0; extra == 'audio'
Requires-Dist: av<19,>=18.1; extra == 'audio'
Requires-Dist: c2pa-python<0.38,>=0.37.10; extra == 'audio'
Requires-Dist: cbor2<6,>=5.6; extra == 'audio'
Requires-Dist: einops; extra == 'audio'
Requires-Dist: numpy>=1.26; extra == 'audio'
Requires-Dist: omegaconf; extra == 'audio'
Requires-Dist: pillow>=10; extra == 'audio'
Requires-Dist: torch>=2.5; extra == 'audio'
Provides-Extra: evidence
Requires-Dist: boto3<2; extra == 'evidence'
Requires-Dist: psycopg[binary,pool]>=3.2; extra == 'evidence'
Provides-Extra: gcs
Requires-Dist: google-cloud-storage<4,>=3.15; extra == 'gcs'
Provides-Extra: image
Requires-Dist: c2pa-python<0.38,>=0.37.10; extra == 'image'
Requires-Dist: cbor2<6,>=5.6; extra == 'image'
Requires-Dist: numpy>=1.26; extra == 'image'
Requires-Dist: onnxruntime==1.24.4; extra == 'image'
Requires-Dist: pillow>=10; extra == 'image'
Requires-Dist: torch>=2.5; extra == 'image'
Requires-Dist: torchvision; extra == 'image'
Requires-Dist: trustmark<0.10,>=0.9.2; extra == 'image'
Provides-Extra: ingest
Requires-Dist: boto3<2; extra == 'ingest'
Requires-Dist: httpx; extra == 'ingest'
Requires-Dist: prometheus-client<1; extra == 'ingest'
Requires-Dist: watchfiles<2; extra == 'ingest'
Provides-Extra: kms
Requires-Dist: boto3<2; extra == 'kms'
Requires-Dist: hvac<3; extra == 'kms'
Provides-Extra: lambda
Requires-Dist: awslambdaric<5,>=4.0.4; extra == 'lambda'
Requires-Dist: boto3<2; extra == 'lambda'
Provides-Extra: server
Requires-Dist: fastapi<1,>=0.115; extra == 'server'
Requires-Dist: httpx; extra == 'server'
Requires-Dist: prometheus-client<1; extra == 'server'
Requires-Dist: python-jsonpath<3,>=2.2.1; extra == 'server'
Requires-Dist: python-multipart<1; extra == 'server'
Requires-Dist: uvicorn[standard]<1; extra == 'server'
Provides-Extra: text
Requires-Dist: c2pa-python<0.38,>=0.37.10; extra == 'text'
Requires-Dist: numpy>=1.26; extra == 'text'
Requires-Dist: pillow>=10; extra == 'text'
Requires-Dist: torch>=2.5; extra == 'text'
Requires-Dist: transformers>=4.46; extra == 'text'
Provides-Extra: video
Requires-Dist: av<19,>=18.1; extra == 'video'
Requires-Dist: c2pa-python<0.38,>=0.37.10; extra == 'video'
Requires-Dist: cbor2<6,>=5.6; extra == 'video'
Requires-Dist: einops; extra == 'video'
Requires-Dist: numpy>=1.26; extra == 'video'
Requires-Dist: omegaconf; extra == 'video'
Requires-Dist: onnxruntime==1.24.4; extra == 'video'
Requires-Dist: pillow>=10; extra == 'video'
Requires-Dist: torch>=2.5; extra == 'video'
Requires-Dist: torchvision; extra == 'video'
Requires-Dist: trustmark<0.10,>=0.9.2; extra == 'video'
Description-Content-Type: text/markdown

# Laidline

Laidline is a marking kit for generative AI providers. Every image, audio clip, video or long text your system
produces leaves signed (a C2PA manifest, shown to readers as Content Credentials, signed with your own key),
watermarked (open models, so anyone can check the result) and logged (a tamper-evident evidence log). Detection is
free for everyone, and the EU AI Act Article 50 paperwork is pre-filled from the log. Laidline runs inside your own
workers: media, models and keys stay on your infrastructure.

## What it marks

- Image: PixelSeal by default, TrustMark selectable, with keyed payloads.
- Audio: AudioSeal, in any container PyAV reads, with streaming sessions for voice agents.
- Video: VideoSeal on a GPU, keyframe TrustMark on a CPU.
- Text: SynthID-style and KGW watermarks, applied through the vLLM and transformers plugins.

`laidline detect` returns graded evidence for any of them. It never says "human-made".

## Install

Laidline needs Python 3.12 or newer. Install the extras for what you mark:

| Extra | What it enables | Command |
|---|---|---|
| (none) | the core: configuration, signing with a local key, the evidence log, the `laidline` CLI | `pip install laidline` |
| `image` | mark and detect images | `pip install "laidline[image]"` |
| `audio` | mark and detect audio | `pip install "laidline[audio]"` |
| `video` | mark and detect video (add `audio` for the soundtrack) | `pip install "laidline[video,audio]"` |
| `text` | detect text watermarks | `pip install "laidline[text]"` |
| `server` | `laidline serve`: the sidecar with native routes and an OpenAI-compatible proxy | `pip install "laidline[server]"` |
| `ingest` | `laidline ingest`: the storage hook for S3, R2 and local directories | `pip install "laidline[ingest]"` |
| `kms` | sign with AWS KMS or Vault/OpenBao Transit | `pip install "laidline[kms]"` |
| `evidence` | S3 and Postgres evidence sinks | `pip install "laidline[evidence]"` |
| `gcs` | Google Cloud Storage ingest | `pip install "laidline[gcs]"` |
| `lambda` | the AWS Lambda entry for the storage hook | `pip install "laidline[lambda]"` |
| `all` | every extra except `lambda` | `pip install "laidline[all]"` |

Combine extras in one line: `pip install "laidline[image,audio,server]"`.

The media extras pull in PyTorch, and the default build from PyPI includes CUDA (about 3.2 GB to download, even on a
host without a GPU). On a CPU-only host, install the CPU build first and the extras after it:

```bash
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install "laidline[image,audio,server]"
```

Model weights download on first use. `laidline models fetch` downloads them ahead of time. The
[install guide](https://laidline.com/docs/install) covers install sizes and GPU setup.

## Hello world

```bash
pip install "laidline[image]"
laidline init --system-name my-image-model --org "Example Org"   # writes laidline.yaml, a payload key and a development certificate
laidline mark in.png                                             # writes in.marked.png and prints its asset id
laidline detect in.marked.png                                    # graded evidence, never "human-made"
```

The same from Python, in your own worker:

```python
from laidline import Marker

marker = Marker.from_config("laidline.yaml")   # load once per process
marked = marker.mark_image("in.png", fmt="png")
open("out.png", "wb").write(marked.data)
```

Until you register, your marks carry a trial issuer number and the shared pool key. They read as a grade D shared
mark: the watermark is found, but it does not identify you. Registering gives you a private mark and a certificate
bound to your name; [Going to production](https://laidline.com/docs/production) walks through it, with a key in your
KMS and a trust-list certificate.

## Plugins and tools

Each plugin is its own package and installs `laidline` with the extras it needs:

- `laidline-comfyui`: a ComfyUI save node that marks every image it writes.
- `laidline-diffusers`: `attach(pipe, marker)` marks every image a diffusers pipeline returns.
- `laidline-vllm`: the vLLM logits processor for the text watermark.
- `laidline-transformers`: a `generate` helper that adds the text watermark.
- `laidline-pipecat`: a Pipecat processor that marks speech from your TTS service.
- `laidline-livekit`: a LiveKit Agents wrapper that marks speech from your TTS node.
- `laidline-bench`: the robustness and latency benchmarks, run with `laidline bench`.

[Integrations](https://laidline.com/docs/integrations/) says which one fits where your outputs are produced.

## Cost

Detection and verification are free, always. Marking is free up to 1,200 credits a month (one image is one credit),
and nothing stops at the cap. Plans, credits and what happens above the free amount are on
[Licensing](https://laidline.com/licensing).

## Licence

Laidline is source-available under the Laidline Source-Available Licence: you can read, run, modify and self-host it,
but not use it to build a competing product or hosted service. It is not open source. Model weights download under
their own licences; the [third-party licences](https://laidline.com/docs/licences) page lists them.

## Documentation

Start with the [quickstart](https://laidline.com/docs/quickstart). The [overview](https://laidline.com/docs/overview)
is the full tour, [configuration](https://laidline.com/docs/config) lists every setting and
[grading](https://laidline.com/docs/grading) explains how to read a detect result.
