Security Model
MyOsicam is designed so that your OScam servers never need to accept inbound connections from the internet, and so that only management-plane metadata — never subscriber data or decryption material — leaves your infrastructure. This page explains the trust relationships between services, how each request is authenticated, and exactly where each category of data lives.
Service architecture overview
A MyOsicam deployment spans three distinct services:
| Service | Role |
|---|---|
Panel (panel.example.com) | Customer-hosted management plane. Stores configuration, schedules jobs, and provides the operator UI. |
| Agent (runs on each OScam server) | Lightweight Go binary installed as a systemd service. Discovers OScam instances, syncs state, and applies changes. |
Admin / License service (admin.myosicam.us) | MyOsicam-operated backend. Manages licenses, quotas, and service-to-service trust (callers). |
Every boundary between these services is protected. The mechanisms differ depending on the relationship, as described in the sections below.
HMAC authentication between services
What it is
When the panel or admin service needs to make an authenticated request to another service — for example, when the panel calls the admin API to validate a license, or when the public pricing page fetches the current plan catalog — the request is signed with a per-caller HMAC-SHA256 signature. The receiving service verifies the signature before processing anything.
How a signed request is structured
Each signed request carries a set of headers:
| Header | Content |
|---|---|
X-Caller-Id | An identifier for the calling service (e.g., public_pricing). |
X-Timestamp | Unix timestamp of the request (integer seconds). |
X-Nonce | A 32-character random hex value — unique per request. |
X-Signature | The HMAC-SHA256 signature (64 hex characters). |
X-Request-Id | A correlation identifier for the request. |
The signature is computed over a canonical string that combines the caller ID, timestamp, nonce, and a SHA-256 hash of the request body. The receiving service recomputes this value from the same inputs and uses a constant-time comparison to check that it matches the provided signature.
Clock-skew protection
The receiving service checks that the X-Timestamp is within an acceptable window of the
server’s current clock (configurable, defaulting to 5 minutes). Requests with timestamps
outside this window are rejected, even if the signature itself is valid.
Replay protection
Each (caller ID, nonce) pair can only be accepted once. The receiving service records the nonce
in a table (hmac_nonces) and rejects any request that presents a nonce it has seen before from
the same caller. This means an attacker who captures a valid signed request cannot replay it —
even an exact copy of all headers will be rejected on the second attempt.
Caller revocation
Each caller has an active / inactive status. A caller whose status is not active is
rejected immediately, regardless of whether the signature is otherwise valid. This allows a
compromised caller key to be revoked without a service restart.
Install tokens
Purpose
When the panel deploys the agent to a new server, it needs a way to authorize that one specific installation — and then immediately invalidate that authorization so it cannot be reused. Install tokens fill this role.
Lifecycle
- Issued: The panel generates a cryptographically random, single-use token just before triggering the SSH install. The token has a fixed expiry window (default: 30 minutes).
- Delivered: The panel injects the token into the bootstrap script and executes it on the target server over SSH. The token lives in memory on the agent’s host for the duration of the install.
- Consumed: The agent presents the token to the panel’s registration endpoint. If the token is valid and unexpired, the panel accepts the registration and immediately marks the token as consumed. No further use is possible.
- Rejected on replay: Any subsequent request presenting the same token — whether an exact
replay or a re-attempt — is rejected. The token’s
consumed_attimestamp is non-null, and the panel refuses to accept it again.
[issued] expires_at in the future, not yet consumed → valid[expired] expires_at has passed, not consumed → rejected[consumed] consumed_at is set (registration succeeded) → rejectedNo binary without a token
The agent binary download endpoint on the install service also requires a valid, unexpired install token. A request with no token, an invalid token, or an expired token is rejected without disclosing any binary content. All download attempts — successful and failed — are logged with the requesting IP and failure reason.
Agent registration and heartbeat
Initial registration
After the bootstrap script installs the agent binary and starts the systemd service, the agent performs a registration call to the panel. This call presents the install token along with system metadata (agent ID, hostname, IP address, OS, and CPU architecture).
The panel validates the install token (see above), then:
- Creates or updates an agent record in the database.
- Generates a new, cryptographically random agent token (64 hex characters — 32 random bytes).
- Returns the agent token to the registering agent.
- Marks the install token as consumed.
The agent writes this token to its local configuration file and uses it for all subsequent communication.
Ongoing heartbeat authentication
After registration, every request the agent sends to the panel — including the periodic heartbeat
and any sync or command-response calls — is authenticated by presenting the agent token as a
Bearer token in the Authorization header. The panel verifies the token on every call and
rejects any request with a missing or incorrect token.
The agent sends a heartbeat on a fixed interval. Each heartbeat carries the agent’s current uptime and a status value. The panel records the agent’s last-seen timestamp on each valid heartbeat, which is how the panel distinguishes a live server from a disconnected or crashed one.
No inbound connections
The agent only makes outbound HTTPS connections to the panel. Your OScam server never needs to accept inbound connections from the internet, and you do not need to open any firewall ports for agent communication.
What data leaves your server
The agent transmits only management-plane metadata to the panel. No subscriber data, no decryption material, and no DVB payload of any kind is ever sent.
Data that is transmitted to the panel
| Category | What is sent |
|---|---|
| Instance list | Names of your OScam instances, their config file paths, working directories, and PID file locations. |
| Configuration summary | Reader count, protocol ports, and global settings read from oscam.conf. |
| User account entries | Usernames, enabled/disabled state, CAID/ident lists from oscam.user. OScam passwords are stored in oscam.user in plain text (an OScam requirement); these are synced to the panel so the panel can write them back. |
| Resource readings | CPU usage (%), RAM consumption (MB), disk usage (MB) — collected from the OS process table for the OScam process. |
| Heartbeat data | Agent host identity (hostname and IP), uptime, and last-seen timestamp. |
| Runtime status | Whether each OScam instance is running or stopped, its process ID, and last-sync timestamp. |
Data that stays on your server
| Category | Where it stays |
|---|---|
| Subscriber card data | Your CA cards and entitlement data never leave the server. The agent reads only the management layer of OScam, not the CA subsystem. |
| DVB decryption material | Decryption keys, ECM/EMM traffic, and any other DVB payload remain on-server and are never transmitted. |
| OScam reader secrets | Reader-level passwords and protocol keys stored in oscam.server are never read or transmitted by the agent. |
| SSH credentials | The SSH password or private key you provide when triggering an agent install is encrypted at rest in the panel database (AES-256-GCM) and is never transmitted outside the panel. |
| Panel encryption key | PANEL_ENCRYPTION_KEY lives in config/.env on your panel host and never leaves it. |
Credential storage at rest
Sensitive fields stored in the panel database are encrypted at rest using AES-256-GCM keyed
by PANEL_ENCRYPTION_KEY. The encrypted fields are:
| Field | Notes |
|---|---|
WebIF passwords (oscam_installs.webif_password) | Read back when the agent must reload the WebIF. |
| Saved SSH server credentials | Used only during the one-time agent install. |
| SMTP / Mailgun keys (if configured) | Used by the panel’s outbound-mail service. |
PANEL_ENCRYPTION_KEY is a 64-character hex string (32 bytes) that lives in config/.env
on your panel host. Rotating it requires re-encrypting the stored values before updating the file.
See Rotating Secrets for the procedure.
Transport security
All communication in the system travels over HTTPS (TLS):
- Agent → panel: outbound HTTPS, initiated by the agent.
- Panel → admin API: HTTPS, signed with HMAC per caller.
- Public site → admin catalog API: HTTPS, HMAC-signed.
- Browser → panel: HTTPS via the TLS certificate provisioned by the panel installer (Let’s Encrypt by default).
The panel installer provisions a TLS certificate as part of the setup. See Install the Panel for the certificate requirements.
Related pages
- Install the Panel — TLS certificate provisioning and panel setup requirements.
- Install the Agent — how install tokens are used during agent deployment.
- Rotating Secrets — rotating the encryption key and agent tokens.
- Agent Install Token Rejected (HTTP 401) — diagnosing token expiry and replay failures.
- Troubleshooting / FAQ — general questions including data privacy and agent crash behaviour.