StegaShield is an application for detecting steganographically manipulated media.
969
Steganography detection REST API (Rust + Axum + PyTorch). Upload an image to receive a probability score indicating whether it contains hidden steganographic content. The PyTorch model is embedded in the binary at build time, so the container has no external service dependencies.
Supported Architectures: linux/amd64, linux/arm64
docker run -d \
--name stegashield \
-p 3000:3000 \
-v stegashield-data:/app/data \
-e LICENSE_TOKEN="<your-license-token>" \
<DOCKERHUB_USER>/stegashield-backend:<TAG>
curl http://localhost:3000/health
# {"status":"ok","model_loaded":true}
The container exits immediately if LICENSE_TOKEN is missing, malformed, or expired.
Image page: https://hub.docker.com/r/5iprojects/stegashield
The container is gated by a per-user, Ed25519-signed license token verified against a public key embedded in the image. The server refuses to serve traffic if the token is missing, malformed, expired, or signed by a different key.
LICENSE_TOKEN environment variable.Tokens may be time-limited; expired tokens must be reissued. On major image versions the embedded public key may rotate, invalidating outstanding tokens. This will be documented explicitly in the corresponding release notes.
All settings are provided as environment variables. Only LICENSE_TOKEN is required.
| Variable | Required | Default | Description |
|---|---|---|---|
LICENSE_TOKEN | Yes | — | Ed25519-signed license token. The server exits with status 1 if the token is missing, empty, malformed, expired, or signed by an unauthorized key. |
PORT | No | 3000 | Bind port inside the container. |
DATABASE_PATH | No | /app/data/stegashield.db | SQLite database file path. Keep this path under /app/data to ensure it is included in the mounted volume. |
MAX_UPLOAD_BYTES | No | 10485760 (10 MB) | Maximum upload size. Requests exceeding this limit return 413 Payload Too Large. |
MAX_IMAGE_DIMENSION | No | 4000 | Maximum width or height in pixels. Images exceeding this limit return 400 Bad Request. |
ALLOWED_EXTENSIONS | No | png,jpg,jpeg,gif,webp,bmp,tiff,tif | Comma-separated lowercase extensions. |
INFERENCE_TIMEOUT_SECS | No | 60 | Maximum time per inference call. Exceeding this limit returns 504 Gateway Timeout. |
CORS_ALLOWED_ORIGINS | No | * | Comma-separated list of origins, or * for any origin. Restrict to specific origins in production deployments. |
RUST_LOG | No | stegashield_backend=info,tower_http=info | tracing-subscriber env-filter expression (for example, debug or stegashield_backend=debug,tower_http=warn). |
Example with custom configuration:
docker run -d \
--name stegashield \
-p 3000:3000 \
-v stegashield-data:/app/data \
-e LICENSE_TOKEN="<your-license-token>" \
-e MAX_UPLOAD_BYTES=52428800 \
-e MAX_IMAGE_DIMENSION=8000 \
-e CORS_ALLOWED_ORIGINS="https://app.example.com" \
-e INFERENCE_TIMEOUT_SECS=120 \
--restart unless-stopped \
<DOCKERHUB_USER>/stegashield-backend:<TAG>
| Volume path | /app/data — SQLite database (analysis history and original image BLOBs). Without a mounted volume, the database is recreated empty on every container restart. |
| Bind-mount UID | The container runs as the non-root user appuser (UID 1000). For host bind mounts, run chown 1000:1000 <host-dir> before starting the container, or use a named volume instead. |
| Port | 3000 (HTTP only — terminate TLS upstream). |
Uploaded images are stored as BLOBs in the SQLite database at /app/data/stegashield.db, alongside each analysis record (filename, probability, label, timestamp). The container makes no outbound network calls; no data is transmitted to external services. To remove stored data, call DELETE /api/analyses to clear the table, or delete the volume with docker volume rm stegashield-data.
| Endpoint | Purpose | Status codes |
|---|---|---|
GET /health | Liveness — returns 200 whenever the process is reachable. | 200 |
GET /ready | Readiness — returns 200 only when the model is loaded; 503 otherwise. | 200 / 503 |
The image's built-in HEALTHCHECK polls /health every 30 seconds. The service is typically ready to accept traffic within 10 seconds of container start, once the embedded model has finished loading. Configure probe initialDelaySeconds (or compose start_period) accordingly.
| Method | Path | Purpose |
|---|---|---|
GET | /health | Liveness probe |
GET | /ready | Readiness probe |
GET | /api/model/info | Model metadata |
POST | /api/analyze | Multipart image upload |
POST | /api/analyze/base64 | JSON { "image": "<base64>", "filename": "..." } |
GET | /api/analyses | List the 50 most recent analyses |
GET | /api/analyses/{id} | Retrieve a single analysis |
GET | /api/analyses/{id}/image | Retrieve the original uploaded image bytes |
DELETE | /api/analyses/{id} | Delete a single analysis |
DELETE | /api/analyses | Delete all analyses |
GET | /swagger-ui/ | Interactive OpenAPI documentation |
GET | /api-docs/openapi.json | Raw OpenAPI 3.1 specification |
Smoke test:
curl -F "[email protected]" http://localhost:3000/api/analyze
The full schema is available at http://localhost:3000/swagger-ui/.
services:
stegashield:
image: <DOCKERHUB_USER>/stegashield-backend:<TAG>
container_name: stegashield-backend
ports:
- "3000:3000"
environment:
- LICENSE_TOKEN=${LICENSE_TOKEN:?LICENSE_TOKEN env var is required}
- MAX_UPLOAD_BYTES=${MAX_UPLOAD_BYTES:-10485760}
- MAX_IMAGE_DIMENSION=${MAX_IMAGE_DIMENSION:-4000}
- ALLOWED_EXTENSIONS=${ALLOWED_EXTENSIONS:-png,jpg,jpeg,gif,webp,bmp,tiff,tif}
- INFERENCE_TIMEOUT_SECS=${INFERENCE_TIMEOUT_SECS:-60}
- CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS:-*}
- RUST_LOG=${RUST_LOG:-stegashield_backend=info,tower_http=info}
volumes:
- stegashield-data:/app/data
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
volumes:
stegashield-data:
Provide LICENSE_TOKEN via a .env file alongside the compose file, and ensure that file is excluded from version control.
Logs are emitted as structured JSON to stdout. Notable events:
| Event | Meaning |
|---|---|
license_activated | License token verified successfully; startup continues. |
license_invalid | License token failed signature, expiration, or format validation; the process exits. |
config_error | A required environment variable is missing; the process exits. |
.pt weights are compiled into the binary and are not present as a separate file. Standard extraction methods such as docker cp cannot retrieve them.appuser account (UID 1000); the no-new-privileges: true option is recommended and is included in the compose snippet above.SIGTERM, completes in-flight requests, and then exits. For longer-running inference workloads, increase the stop grace period (for example, --stop-timeout 30).| Symptom | Cause | Resolution |
|---|---|---|
Container exits immediately; log message: LICENSE_TOKEN env var is required | Token unset or empty | Set the LICENSE_TOKEN environment variable |
Container exits immediately; log message: license_invalid | Token is malformed, expired, or signed by an unauthorized key | Request a new token from the licensing form |
GET /ready returns 503 indefinitely | Model failed to load (rare; the model is embedded in the binary) | Inspect container logs for inference initialization errors |
413 Payload Too Large on upload | Upload size exceeds MAX_UPLOAD_BYTES | Increase MAX_UPLOAD_BYTES |
400 Bad Request with image too large | Image dimensions exceed MAX_IMAGE_DIMENSION | Increase MAX_IMAGE_DIMENSION |
400 Bad Request with unsupported extension | Extension not in ALLOWED_EXTENSIONS | Add the extension (lowercase, without a leading dot) |
504 Gateway Timeout | Inference exceeded INFERENCE_TIMEOUT_SECS | Increase the timeout or reduce the input image size |
| Browser CORS error | Origin not listed in CORS_ALLOWED_ORIGINS | Add the origin to CORS_ALLOWED_ORIGINS |
| Analysis history lost after restart | /app/data not on a persistent volume | Mount -v stegashield-data:/app/data |
Bind-mount writes fail with permission denied | Host directory not writable by UID 1000 | Run chown 1000:1000 <host-dir>, or use a named volume |
Copyright (c) 2026 Five Insights, LLC. All Rights Reserved.
Permission is granted to individuals and organizations ("User") to use this software project ("Software") solely through authorized access methods provided by Five Insights, LLC, including authentication tokens issued via email.
This license does not grant ownership of the Software or any intellectual property rights associated with it.
Users may not:
All rights not expressly granted are reserved by Five Insights, LLC.
Access to the Software may require a valid authentication token provided by Five Insights, LLC through email or other approved communication methods.
Five Insights, LLC reserves the right to revoke, suspend, or limit access at any time for any reason without notice.
The Software and all associated intellectual property rights remain the exclusive property of Five Insights, LLC.
This license does not transfer any ownership rights to the User.
THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
FIVE INSIGHTS, LLC DOES NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED, ERROR-FREE, SECURE, OR FREE OF DEFECTS.
TO THE MAXIMUM EXTENT PERMITTED BY LAW, FIVE INSIGHTS, LLC, ITS AFFILIATES, OWNERS, EMPLOYEES, AND CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES, CLAIMS, LOSSES, OR LIABILITIES ARISING FROM OR RELATED TO:
USE OF THE SOFTWARE IS ENTIRELY AT THE USER'S OWN RISK.
This license automatically terminates if the User violates any provision of this agreement.
Upon termination, the User must cease all use of the Software and destroy any copies or access credentials in their possession.
This license shall be governed by and construed in accordance with the laws of the State of Texas, United States, without regard to conflict of law principles.
For licensing inquiries or authorization requests, contact:
Copyright © 2026 Five Insights. All rights reserved.
Content type
Image
Digest
sha256:64a6a3785…
Size
368.9 MB
Last updated
4 months ago
docker pull 5iprojects/stegashield