Skip to content
myosicam.us

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:

ServiceRole
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:

HeaderContent
X-Caller-IdAn identifier for the calling service (e.g., public_pricing).
X-TimestampUnix timestamp of the request (integer seconds).
X-NonceA 32-character random hex value — unique per request.
X-SignatureThe HMAC-SHA256 signature (64 hex characters).
X-Request-IdA 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

  1. 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).
  2. 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.
  3. 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.
  4. Rejected on replay: Any subsequent request presenting the same token — whether an exact replay or a re-attempt — is rejected. The token’s consumed_at timestamp is non-null, and the panel refuses to accept it again.
Install token states
[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) → rejected

No 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:

  1. Creates or updates an agent record in the database.
  2. Generates a new, cryptographically random agent token (64 hex characters — 32 random bytes).
  3. Returns the agent token to the registering agent.
  4. 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

CategoryWhat is sent
Instance listNames of your OScam instances, their config file paths, working directories, and PID file locations.
Configuration summaryReader count, protocol ports, and global settings read from oscam.conf.
User account entriesUsernames, 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 readingsCPU usage (%), RAM consumption (MB), disk usage (MB) — collected from the OS process table for the OScam process.
Heartbeat dataAgent host identity (hostname and IP), uptime, and last-seen timestamp.
Runtime statusWhether each OScam instance is running or stopped, its process ID, and last-sync timestamp.

Data that stays on your server

CategoryWhere it stays
Subscriber card dataYour CA cards and entitlement data never leave the server. The agent reads only the management layer of OScam, not the CA subsystem.
DVB decryption materialDecryption keys, ECM/EMM traffic, and any other DVB payload remain on-server and are never transmitted.
OScam reader secretsReader-level passwords and protocol keys stored in oscam.server are never read or transmitted by the agent.
SSH credentialsThe 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 keyPANEL_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:

FieldNotes
WebIF passwords (oscam_installs.webif_password)Read back when the agent must reload the WebIF.
Saved SSH server credentialsUsed 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.