Sign inSign up

5iprojects/stegashield

By 5iprojects

•Updated 4 months ago

StegaShield is an application for detecting steganographically manipulated media.

Image
Networking
Security
Machine learning & AI
0

969

5iprojects/stegashield repository overview

⁠Stegashield Backend

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


⁠Quick start

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⁠


⁠Obtaining a license token

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.

  1. Submit your email at https://stegashield.5iprojects.com/⁠.
  2. You will receive the token by email.
  3. Provide the token to the container via the 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.


⁠Configuration

All settings are provided as environment variables. Only LICENSE_TOKEN is required.

VariableRequiredDefaultDescription
LICENSE_TOKENYes—Ed25519-signed license token. The server exits with status 1 if the token is missing, empty, malformed, expired, or signed by an unauthorized key.
PORTNo3000Bind port inside the container.
DATABASE_PATHNo/app/data/stegashield.dbSQLite database file path. Keep this path under /app/data to ensure it is included in the mounted volume.
MAX_UPLOAD_BYTESNo10485760 (10 MB)Maximum upload size. Requests exceeding this limit return 413 Payload Too Large.
MAX_IMAGE_DIMENSIONNo4000Maximum width or height in pixels. Images exceeding this limit return 400 Bad Request.
ALLOWED_EXTENSIONSNopng,jpg,jpeg,gif,webp,bmp,tiff,tifComma-separated lowercase extensions.
INFERENCE_TIMEOUT_SECSNo60Maximum time per inference call. Exceeding this limit returns 504 Gateway Timeout.
CORS_ALLOWED_ORIGINSNo*Comma-separated list of origins, or * for any origin. Restrict to specific origins in production deployments.
RUST_LOGNostegashield_backend=info,tower_http=infotracing-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 and port

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 UIDThe 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.
Port3000 (HTTP only — terminate TLS upstream).

⁠Data handling

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.


⁠Health and readiness

EndpointPurposeStatus codes
GET /healthLiveness — returns 200 whenever the process is reachable.200
GET /readyReadiness — 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.


⁠API quick reference

MethodPathPurpose
GET/healthLiveness probe
GET/readyReadiness probe
GET/api/model/infoModel metadata
POST/api/analyzeMultipart image upload
POST/api/analyze/base64JSON { "image": "<base64>", "filename": "..." }
GET/api/analysesList the 50 most recent analyses
GET/api/analyses/{id}Retrieve a single analysis
GET/api/analyses/{id}/imageRetrieve the original uploaded image bytes
DELETE/api/analyses/{id}Delete a single analysis
DELETE/api/analysesDelete all analyses
GET/swagger-ui/Interactive OpenAPI documentation
GET/api-docs/openapi.jsonRaw 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/.


⁠Docker Compose

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.


⁠Logging

Logs are emitted as structured JSON to stdout. Notable events:

EventMeaning
license_activatedLicense token verified successfully; startup continues.
license_invalidLicense token failed signature, expiration, or format validation; the process exits.
config_errorA required environment variable is missing; the process exits.

⁠Security

  • License-gated — the server refuses to serve traffic without a valid token verified against the embedded public key.
  • Embedded model — the PyTorch .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.
  • Non-root execution — the process runs as the appuser account (UID 1000); the no-new-privileges: true option is recommended and is included in the compose snippet above.
  • Graceful shutdown — the process listens for SIGTERM, completes in-flight requests, and then exits. For longer-running inference workloads, increase the stop grace period (for example, --stop-timeout 30).
  • Input validation — uploads are validated by file extension, magic bytes, dimensions, and byte size before reaching the model.

⁠Troubleshooting

SymptomCauseResolution
Container exits immediately; log message: LICENSE_TOKEN env var is requiredToken unset or emptySet the LICENSE_TOKEN environment variable
Container exits immediately; log message: license_invalidToken is malformed, expired, or signed by an unauthorized keyRequest a new token from the licensing form
GET /ready returns 503 indefinitelyModel failed to load (rare; the model is embedded in the binary)Inspect container logs for inference initialization errors
413 Payload Too Large on uploadUpload size exceeds MAX_UPLOAD_BYTESIncrease MAX_UPLOAD_BYTES
400 Bad Request with image too largeImage dimensions exceed MAX_IMAGE_DIMENSIONIncrease MAX_IMAGE_DIMENSION
400 Bad Request with unsupported extensionExtension not in ALLOWED_EXTENSIONSAdd the extension (lowercase, without a leading dot)
504 Gateway TimeoutInference exceeded INFERENCE_TIMEOUT_SECSIncrease the timeout or reduce the input image size
Browser CORS errorOrigin not listed in CORS_ALLOWED_ORIGINSAdd the origin to CORS_ALLOWED_ORIGINS
Analysis history lost after restart/app/data not on a persistent volumeMount -v stegashield-data:/app/data
Bind-mount writes fail with permission deniedHost directory not writable by UID 1000Run chown 1000:1000 <host-dir>, or use a named volume

⁠Proprietary Software License

Copyright (c) 2026 Five Insights, LLC. All Rights Reserved.

⁠1. License Grant

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.

⁠2. Restrictions

Users may not:

  • Copy, redistribute, sublicense, sell, lease, or commercially exploit the Software without prior written permission from Five Insights, LLC
  • Modify, reverse engineer, decompile, disassemble, or create derivative works based on the Software
  • Remove or alter any copyright, trademark, or proprietary notices
  • Share or transfer authentication tokens to unauthorized parties
  • Use the Software for unlawful purposes

All rights not expressly granted are reserved by Five Insights, LLC.

⁠3. Authentication Access

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.

⁠4. Ownership

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.

⁠5. Disclaimer of Warranty

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.

⁠6. Limitation of Liability

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 OR INABILITY TO USE THE SOFTWARE
  • SOFTWARE FAILURES, BUGS, OR ERRORS
  • DATA LOSS OR SECURITY INCIDENTS
  • BUSINESS INTERRUPTION
  • THIRD-PARTY MISUSE
  • ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES

USE OF THE SOFTWARE IS ENTIRELY AT THE USER'S OWN RISK.

⁠7. Termination

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.

⁠8. Governing Law

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.

⁠9. Contact

For licensing inquiries or authorization requests, contact:

[email protected]⁠


Copyright © 2026 Five Insights. All rights reserved.

Tag summary

Content type

Image

Digest

sha256:64a6a3785…

Size

368.9 MB

Last updated

4 months ago

docker pull 5iprojects/stegashield