{"id":36400121,"url":"https://github.com/dmriding/talos","last_synced_at":"2026-01-26T15:04:18.304Z","repository":{"id":331512524,"uuid":"887954383","full_name":"dmriding/talos","owner":"dmriding","description":"Talos Rust Licensing Library - By NetViper","archived":false,"fork":false,"pushed_at":"2026-01-21T19:15:37.000Z","size":860,"stargazers_count":19,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-22T04:23:08.761Z","etag":null,"topics":["library","license","license-management","rust"],"latest_commit_sha":null,"homepage":"https://netviper.gr","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmriding.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"code_of_conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-13T15:09:09.000Z","updated_at":"2026-01-21T19:16:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dmriding/talos","commit_stats":null,"previous_names":["dmriding/talos"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/dmriding/talos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmriding%2Ftalos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmriding%2Ftalos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmriding%2Ftalos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmriding%2Ftalos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmriding","download_url":"https://codeload.github.com/dmriding/talos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmriding%2Ftalos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28781308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T13:55:28.044Z","status":"ssl_error","status_checked_at":"2026-01-26T13:55:26.068Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["library","license","license-management","rust"],"created_at":"2026-01-11T16:04:38.202Z","updated_at":"2026-01-26T15:04:18.298Z","avatar_url":"https://github.com/dmriding.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Talos — Secure Rust Licensing System\n\n[![Crates.io](https://img.shields.io/crates/v/netviper-talos.svg)](https://crates.io/crates/netviper-talos)\n[![Documentation](https://docs.rs/netviper-talos/badge.svg)](https://docs.rs/netviper-talos)\n[![Downloads](https://img.shields.io/crates/d/netviper-talos.svg)](https://crates.io/crates/netviper-talos)\n[![Build Status](https://github.com/dmriding/talos/actions/workflows/ci.yml/badge.svg)](https://github.com/dmriding/talos/actions)\n[![codecov](https://codecov.io/gh/dmriding/talos/graph/badge.svg)](https://codecov.io/gh/dmriding/talos)\n[![License](https://img.shields.io/badge/license-MIT-blue)](https://github.com/dmriding/talos/blob/main/LICENSE)\n[![Rust](https://img.shields.io/badge/rust-stable-orange.svg)](https://www.rust-lang.org/)\n\n**Talos** is a Rust-based secure licensing framework providing:\n\n- Hardware-bound licensing\n- Encrypted license storage\n- License activation/validation\n- Heartbeat-based liveness checks\n- A lightweight Axum server backend\n- A robust async client library\n\nYour software gets a reliable, secure \"gatekeeper,\" inspired by **Talos**, the mythological bronze guardian who protected Crete.\n\n---\n\n## Overview\n\nTalos offers:\n\n- A **client library** for embedding license logic inside your application\n- A **server component** for verifying, activating, and tracking licenses\n- Full async, cross-platform compatibility (Windows, macOS, Linux)\n- Strong cryptography (AES-256-GCM + SHA-256 hardware fingerprinting)\n\nTalos is built to be **easy to integrate yet extremely hard to bypass**.\n\n---\n\n## Key Features\n\n- **Hardware Binding** — Licenses tied to CPU + motherboard fingerprint\n- **Secure OS Keyring Storage** — License data stored in Windows Credential Manager, macOS Keychain, or Linux Secret Service\n- **AES-256-GCM Encryption** — License data encrypted with hardware-derived keys\n- **Networked License Control** — Activate/validate/deactivate remotely\n- **Heartbeat System** — Keeps licenses alive and trackable\n- **SQLite \u0026 Postgres Support** — Choose your storage backend\n- **Self-Hostable** — Easy to deploy, zero external dependencies\n- **Fully Async** — Powered by `tokio`, `axum`, `reqwest`, `sqlx`\n- **Strong Test Coverage** — Unit tests + integration tests\n\n---\n\n## How It Works\n\n1. Talos generates a **hardware fingerprint** using CPU + motherboard identifiers (hashed via SHA-256).\n2. License data is encrypted using **AES-256-GCM** with a hardware-derived key.\n3. Encrypted data is stored securely in the **OS keyring** (with fallback to app data directory).\n4. Client communicates with the server using HTTPS via `reqwest`.\n5. Server stores licenses and heartbeat timestamps via SQLx.\n6. A small REST API allows:\n   - Activation\n   - Validation\n   - Deactivation\n   - Heartbeat updates\n\n---\n\n## Project Structure\n\n```plaintext\ntalos/\n├── src/\n│   ├── client/\n│   │   ├── license.rs            # License struct + client operations\n│   │   ├── storage.rs            # Keyring + file storage abstraction\n│   │   ├── encrypted_storage.rs  # AES-256-GCM encrypted storage\n│   │   ├── heartbeat.rs          # Heartbeat HTTP operations\n│   │   ├── key_generation.rs     # Device key helpers\n│   │   └── main.rs               # Example client binary\n│   ├── server/\n│   │   ├── database.rs           # SQLite/Postgres abstraction\n│   │   ├── handlers.rs           # Axum handlers for /activate, /validate...\n│   │   ├── admin.rs              # Admin API handlers (feature-gated)\n│   │   ├── auth.rs               # JWT authentication (feature-gated)\n│   │   ├── routes.rs             # Router builder\n│   │   ├── server_sim.rs         # In-memory simulation for tests\n│   │   └── main.rs               # Server binary\n│   ├── config.rs                 # Config loader (config.toml + env vars)\n│   ├── encryption.rs             # AES-256-GCM utilities\n│   ├── errors.rs                 # Custom LicenseError type\n│   ├── hardware.rs               # Cross-platform hardware fingerprinting\n│   ├── license_key.rs            # License key generation/validation\n│   ├── tiers.rs                  # Tier configuration system\n│   └── lib.rs                    # Library entry point\n├── tests/                        # Unit and integration tests\n├── examples/                     # Usage examples\n├── migrations/                   # Database migrations\n├── docs/\n│   ├── public/\n│   │   └── ROADMAP.md            # Development roadmap\n│   ├── api/                      # API reference documentation\n│   │   ├── rest-api.md           # Complete REST API reference\n│   │   └── openapi.json          # OpenAPI 3.1.0 specification\n│   ├── examples/                 # Complete runnable examples\n│   │   ├── basic-client/         # Minimal client integration\n│   │   ├── air-gapped/           # Offline validation example\n│   │   └── feature-gating/       # Feature gating example\n│   └── guide/                    # User guides\n│       ├── getting-started.md    # 5-minute quickstart\n│       ├── client-integration.md # Client library usage\n│       ├── server-deployment.md  # Production deployment\n│       ├── admin-api.md          # Admin API guide\n│       └── troubleshooting.md    # Debugging and FAQ\n├── .claude/\n│   └── README.md                 # AI assistant context (for contributors)\n├── config.toml.example           # Example configuration\n├── .env.example                  # Example environment variables\n├── Cargo.toml\n└── README.md\n```\n\n---\n\n## Prerequisites\n\n- Rust (stable)\n- SQLite **or** PostgreSQL\n- `sqlx-cli` (for running migrations)\n\nInstall Rust:\n\n```sh\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\nrustup update\n```\n\nInstall SQLx CLI:\n\n```sh\ncargo install sqlx-cli\n```\n\n---\n\n## Installation\n\nAdd Talos to your project:\n\n```toml\n[dependencies]\ntalos = \"0.2\"\n```\n\nThen:\n\n```sh\ncargo build\n```\n\n---\n\n## Feature Flags\n\nTalos uses Cargo feature flags to let you include only what you need:\n\n| Feature | Default | Description |\n|---------|---------|-------------|\n| `server` | Yes | Server components (handlers, database) |\n| `sqlite` | Yes | SQLite database backend |\n| `postgres` | No | PostgreSQL database backend |\n| `jwt-auth` | No | JWT authentication middleware for protected endpoints |\n| `admin-api` | No | Admin CRUD API for license management |\n| `rate-limiting` | No | Rate limiting middleware for abuse prevention |\n| `background-jobs` | No | Scheduled background jobs for license maintenance |\n| `openapi` | No | OpenAPI 3.0 specification and Swagger UI |\n\n### Examples\n\n```toml\n# Default: server + SQLite\ntalos = \"0.2\"\n\n# Client-only (no server components)\ntalos = { version = \"0.2\", default-features = false }\n\n# Server with PostgreSQL instead of SQLite\ntalos = { version = \"0.2\", default-features = false, features = [\"server\", \"postgres\"] }\n\n# Server with both SQLite and PostgreSQL\ntalos = { version = \"0.2\", features = [\"postgres\"] }\n\n# Full server with admin API and JWT auth\ntalos = { version = \"0.2\", features = [\"admin-api\", \"jwt-auth\"] }\n\n# Server with background jobs enabled\ntalos = { version = \"0.2\", features = [\"background-jobs\"] }\n\n# Full-featured server\ntalos = { version = \"0.2\", features = [\"admin-api\", \"jwt-auth\", \"rate-limiting\", \"background-jobs\"] }\n\n# Server with OpenAPI documentation\ntalos = { version = \"0.2\", features = [\"admin-api\", \"openapi\"] }\n```\n\n---\n\n## Quick Start\n\n### 1. Configure\n\nCopy the example configuration files:\n\n```sh\ncp config.toml.example config.toml\ncp .env.example .env\n```\n\nEdit `config.toml` as needed:\n\n```toml\nserver_url = \"http://127.0.0.1:8080\"\nheartbeat_interval = 60\nenable_logging = true\n\n[database]\ndb_type = \"sqlite\"\nsqlite_url = \"sqlite://talos.db\"\n```\n\n### 2. Run Migrations\n\n```sh\nsqlx migrate run\n```\n\n### 3. Start the Server\n\n```sh\ncargo run --bin talos_server\n```\n\n### 4. Use the Client\n\n```rust\nuse talos::client::License;\nuse talos::errors::LicenseResult;\n\n#[tokio::main]\nasync fn main() -\u003e LicenseResult\u003c()\u003e {\n    // Create a new license client\n    let mut license = License::new(\n        \"LIC-XXXX-XXXX-XXXX\".to_string(),  // Your license key\n        \"http://127.0.0.1:8080\".to_string(),\n    );\n\n    // Bind to this hardware (replaces activate())\n    let bind_result = license.bind(Some(\"My Workstation\"), None).await?;\n    println!(\"License bound. Features: {:?}\", bind_result.features);\n\n    // Validate the license\n    let validation = license.validate().await?;\n    if validation.has_feature(\"feature_a\") {\n        println!(\"Feature A is enabled!\");\n    }\n\n    // Check a specific feature\n    let feature_result = license.validate_feature(\"premium_export\").await?;\n    if feature_result.allowed {\n        println!(\"Premium export is available\");\n    }\n\n    // Send heartbeat\n    let heartbeat = license.heartbeat().await?;\n    println!(\"Server time: {}\", heartbeat.server_time);\n\n    // Release when done (replaces deactivate())\n    license.release().await?;\n\n    Ok(())\n}\n```\n\n### Air-Gapped Systems\n\nFor systems that need to operate offline within a grace period:\n\n```rust\nuse talos::client::License;\n\nasync fn check_license_with_fallback() -\u003e bool {\n    let mut license = License::load_from_disk().await.unwrap();\n\n    // Try online validation first, fall back to cached offline validation\n    match license.validate_with_fallback().await {\n        Ok(result) =\u003e {\n            if let Some(warning) = \u0026result.warning {\n                // System should go online soon\n                eprintln!(\"Warning: {}\", warning);\n            }\n            true\n        }\n        Err(e) =\u003e {\n            eprintln!(\"License validation failed: {}\", e);\n            false\n        }\n    }\n}\n```\n\nOr run the provided example:\n\n```sh\ncargo run --example manual_activate\n```\n\n---\n\n## Server API Endpoints\n\n### OpenAPI Documentation (requires `openapi` feature)\n\nWhen running with the `openapi` feature enabled, interactive API documentation is available:\n\n| Endpoint                | Description                        |\n|-------------------------|------------------------------------|\n| `/swagger-ui`           | Swagger UI for interactive API exploration |\n| `/api-docs/openapi.json`| OpenAPI 3.0 specification (JSON)   |\n\nRun the server with OpenAPI enabled:\n\n```sh\ncargo run --bin talos_server --features \"openapi,admin-api\"\n```\n\nThen navigate to `http://127.0.0.1:8080/swagger-ui` in your browser.\n\n### System Endpoints (always available)\n\n| Method | Endpoint      | Description                        |\n|--------|---------------|------------------------------------|\n| GET    | `/health`     | Health check with database status  |\n\nThe health endpoint returns:\n\n```json\n{\n  \"status\": \"healthy\",\n  \"service\": \"talos\",\n  \"version\": \"0.2.2\",\n  \"database\": {\n    \"connected\": true,\n    \"db_type\": \"sqlite\"\n  }\n}\n```\n\n### Legacy Client Endpoints (always available)\n\n| Method | Endpoint      | Description              |\n|--------|---------------|--------------------------|\n| POST   | `/activate`   | Activate a license       |\n| POST   | `/validate`   | Validate if license is active |\n| POST   | `/deactivate` | Deactivate a license     |\n| POST   | `/heartbeat`  | Send heartbeat ping      |\n\n### Client API v1 Endpoints (always available)\n\n| Method | Endpoint                        | Description                     |\n|--------|---------------------------------|---------------------------------|\n| POST   | `/api/v1/client/bind`           | Bind license to hardware        |\n| POST   | `/api/v1/client/release`        | Release license from hardware   |\n| POST   | `/api/v1/client/validate`       | Validate a license              |\n| POST   | `/api/v1/client/validate-or-bind` | Validate or auto-bind         |\n| POST   | `/api/v1/client/heartbeat`      | Send heartbeat                  |\n| POST   | `/api/v1/client/validate-feature` | Validate feature access       |\n\n### Admin Endpoints (requires `admin-api` feature)\n\n| Method | Endpoint                              | Description                        |\n|--------|---------------------------------------|------------------------------------|\n| POST   | `/api/v1/licenses`                    | Create a new license               |\n| POST   | `/api/v1/licenses/batch`              | Batch create licenses              |\n| GET    | `/api/v1/licenses/{id}`               | Get license by ID                  |\n| GET    | `/api/v1/licenses?org_id=X`           | List licenses by org               |\n| PATCH  | `/api/v1/licenses/{id}`               | Update a license                   |\n| POST   | `/api/v1/licenses/{id}/revoke`        | Revoke a license (with optional grace period) |\n| POST   | `/api/v1/licenses/{id}/reinstate`     | Reinstate a suspended/revoked license |\n| POST   | `/api/v1/licenses/{id}/extend`        | Extend license expiration          |\n| PATCH  | `/api/v1/licenses/{id}/usage`         | Update usage/bandwidth metrics     |\n| POST   | `/api/v1/licenses/{id}/release`       | Release hardware binding           |\n| POST   | `/api/v1/licenses/{id}/blacklist`     | Permanently blacklist a license    |\n\n### Token Endpoints (requires `admin-api` feature)\n\n| Method | Endpoint                 | Description              |\n|--------|--------------------------|--------------------------|\n| POST   | `/api/v1/tokens`         | Create a new API token   |\n| GET    | `/api/v1/tokens`         | List all API tokens      |\n| GET    | `/api/v1/tokens/{id}`    | Get token details        |\n| DELETE | `/api/v1/tokens/{id}`    | Revoke a token           |\n\nAll legacy client requests use:\n\n```json\n{\n  \"license_id\": \"LICENSE-12345\",\n  \"client_id\": \"CLIENT-67890\"\n}\n```\n\n### Example\n\n```sh\ncurl -X POST http://127.0.0.1:8080/validate \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"license_id\":\"LICENSE-12345\",\"client_id\":\"CLIENT-67890\"}'\n```\n\n---\n\n## Error Response Format\n\nAll API endpoints return errors in a standardized JSON format:\n\n```json\n{\n  \"error\": {\n    \"code\": \"LICENSE_NOT_FOUND\",\n    \"message\": \"The requested license does not exist\",\n    \"details\": null\n  }\n}\n```\n\n### Error Codes\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| **License State** |||\n| `LICENSE_NOT_FOUND` | 404 | License key does not exist |\n| `LICENSE_EXPIRED` | 403 | License has expired |\n| `LICENSE_REVOKED` | 403 | License has been revoked |\n| `LICENSE_SUSPENDED` | 403 | License is temporarily suspended |\n| `LICENSE_BLACKLISTED` | 403 | License is permanently blacklisted |\n| `LICENSE_INACTIVE` | 403 | License is not active |\n| **Hardware Binding** |||\n| `ALREADY_BOUND` | 409 | License is bound to another device |\n| `NOT_BOUND` | 409 | License is not bound to any device |\n| `HARDWARE_MISMATCH` | 403 | Hardware ID doesn't match bound device |\n| **Features \u0026 Quotas** |||\n| `FEATURE_NOT_INCLUDED` | 403 | Feature not in license tier |\n| `QUOTA_EXCEEDED` | 403 | Usage quota exceeded |\n| **Validation** |||\n| `INVALID_REQUEST` | 400 | Request payload is invalid |\n| `MISSING_FIELD` | 400 | Required field is missing |\n| `INVALID_FIELD` | 400 | Field value is invalid |\n| **Authentication** |||\n| `MISSING_TOKEN` | 401 | No authorization token provided |\n| `INVALID_HEADER` | 400 | Authorization header malformed |\n| `INVALID_TOKEN` | 401 | Token is invalid |\n| `TOKEN_EXPIRED` | 401 | Token has expired |\n| `INSUFFICIENT_SCOPE` | 403 | Token lacks required permissions |\n| `AUTH_DISABLED` | 501 | Authentication not configured |\n| **Server Errors** |||\n| `NOT_FOUND` | 404 | Resource not found |\n| `CONFLICT` | 409 | Operation conflicts with current state |\n| `DATABASE_ERROR` | 500 | Database operation failed |\n| `CONFIG_ERROR` | 500 | Server configuration error |\n| `CRYPTO_ERROR` | 500 | Encryption operation failed |\n| `NETWORK_ERROR` | 502 | External service communication failed |\n| `INTERNAL_ERROR` | 500 | Unexpected server error |\n\n---\n\n## Testing\n\nRun all tests:\n\n```sh\ncargo test\n```\n\nRun with all features enabled:\n\n```sh\ncargo test --features \"admin-api,jwt-auth\"\n```\n\nRun with logging:\n\n```sh\nRUST_LOG=info cargo test\n```\n\n---\n\n## Roadmap\n\nSee the full [ROADMAP.md](docs/public/ROADMAP.md) for detailed development plans.\n\n**Current Status: v0.2.2**\n\nTalos is a fully-featured, production-ready licensing system with:\n\n- License activation/validation/deactivation with bind/release workflow\n- Heartbeat mechanism with grace period support\n- Hardware binding (SHA-256 fingerprint)\n- Encrypted storage (AES-256-GCM)\n- Configurable license key generation\n- Tier-based feature system with configurable tiers\n- Organization/tenant grouping (1 org = N licenses)\n- Bandwidth/quota tracking exposed in validation responses\n- JWT authentication middleware\n- Admin API (CRUD operations)\n- Rate limiting middleware\n- License lifecycle management (suspend, revoke, reinstate, extend)\n- Background jobs (grace period expiration, license expiration, stale device cleanup)\n- License blacklisting (permanent ban with audit trail)\n- OpenAPI 3.0 specification with Swagger UI\n- Standardized error response format\n- Updated client library with v1 API methods (bind/release/validate/validate-feature/heartbeat)\n- Secure encrypted cache for offline/air-gapped system support\n- Admin API IP whitelisting (CIDR support, IPv4/IPv6, proxy header support)\n\n**Upcoming:**\n\n- Audit logging\n- API key rotation\n- Webhook notifications\n- Dashboard UI\n- Analytics and reporting\n\n## Documentation\n\nComprehensive documentation is available in the `docs/` folder:\n\n### Guides\n\n| Guide | Description |\n|-------|-------------|\n| [Getting Started](docs/guide/getting-started.md) | 5-minute quickstart with feature flags and setup |\n| [Client Integration](docs/guide/client-integration.md) | Full client lifecycle, offline validation, feature gating |\n| [Server Deployment](docs/guide/server-deployment.md) | Database setup, Docker, nginx/traefik, production checklist |\n| [Admin API](docs/guide/admin-api.md) | All admin endpoints, authentication, security best practices |\n| [Troubleshooting](docs/guide/troubleshooting.md) | Common errors, debugging tips, FAQ |\n\n### API Reference\n\n| Resource | Description |\n|----------|-------------|\n| [REST API Reference](docs/api/rest-api.md) | Complete endpoint documentation with examples |\n| [OpenAPI Spec](docs/api/openapi.json) | OpenAPI 3.1.0 specification |\n| `/swagger-ui` | Interactive API explorer (when running with `openapi` feature) |\n\n### Examples\n\nComplete, runnable examples are available in `docs/examples/`:\n\n| Example | Description |\n|---------|-------------|\n| [basic-client](docs/examples/basic-client/) | Minimal client integration with runtime license key entry |\n| [air-gapped](docs/examples/air-gapped/) | Offline validation with encrypted cache and grace periods |\n| [feature-gating](docs/examples/feature-gating/) | Enable/disable features based on license tier |\n\nEach example includes a README with step-by-step instructions for both Windows (PowerShell) and Mac/Linux (bash).\n\n---\n\n## Contributing\n\nPRs, issues, and discussions are all welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmriding%2Ftalos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmriding%2Ftalos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmriding%2Ftalos/lists"}