SesamePortal is a local PHP surveillance portal for SesameDVR installations. It manages DVR servers, users, groups, cameras, per-user playback tokens, favorites, and provides camera list, map and saved video wall pages backed by a SesameDVR auth backend.
php bin/portal migrate
php bin/portal create-admin admin admin123
php -S 127.0.0.1:8080 -t publicOpen http://127.0.0.1:8080.
Default local state is stored in var/portal.sqlite. Production installs use
/var/lib/sesame-portal.
SQLite is the default storage backend. PostgreSQL/MySQL can be selected through config or environment variables:
'db_dsn' => 'pgsql:host=127.0.0.1;port=5432;dbname=sesame_portal',
'db_user' => 'sesame_portal',
'db_password' => 'secret',The same values can be passed as SESAME_PORTAL_DB_DSN,
SESAME_PORTAL_DB_USER, and SESAME_PORTAL_DB_PASSWORD.
The UI supports the same language set as SesameDVR: ru, en, de, fr,
es, it, pt, bg, pl, zh, ja, ko, ar, and hy. The default
language is configured with locale or SESAME_PORTAL_LOCALE; users can
switch from the language dropdown or with ?lang=<code>.
Each camera can run in one of three modes:
managed: SesamePortal writes the stream configuration to the selected SesameDVR server through the management API. The stream title (display_name/displayName) is sent as the streamdisplayName;dvr_stream_namestays the URL-safe technical stream name used by DVR endpoints.edge_agent: SesamePortal creates a push stream on the DVR withpublisherKind=agent, linked toagent_idandagent_camera_id.read_only: SesamePortal does not change DVR configuration and only uses the selected DVR server plusdvr_stream_namefor preview, auth, and playback.
Per camera, Portal can add an HTML/CSS watermark with the current user's login over the Portal player and control its intensity. The video stream is not transcoded for this.
The List page (formerly Mosaic, still at /) supports all/favorites/group filtering, case-insensitive search by
camera title or technical stream name, pagination, and a 2-6 cameras-per-row
density switch. Page size follows the selected density: 4/6/12/15/18 cameras for
2/3/4/5/6 columns. It uses fixed 16:9 camera cards. Preview images are
preloaded behind a loader and then swapped in, so refreshes do not show
half-loaded images. The preview refresh interval is configurable in Personal settings → List,
including an Off mode. If a DVR stream is offline, the card shows Stream unavailable; an old preview may still be shown with that status overlay.
The map view supports the same filters and search. It auto-fits the current camera set, clusters nearby cameras at lower zoom levels, shows camera direction/FOV markers, and exposes the same favorite toggle as the list.
Video walls (/video-walls) are named, personal camera layouts. Administrators
can manage all walls; other users can only manage their own. The editor provides
a group tree, search, drag-and-drop/button ordering and a 1×1 to 6×6 grid.
Selected cameras must fit the grid. Each cell uses a separate DVR embed
player; Portal does not transcode video. Walls support shared archive seeking,
play/pause, 0.5x-8x speed, LIVE and full screen. One embed-style timeline combines
recordings and events from all cameras into two logical-OR lanes; gaps and
buffering do not move the other cameras. Captions overlay video, tiles have no
spacing, and fullscreen playback controls hide when idle.
Shared playback requires an updated DVR with wall-control protocol v1.
Users with hidden archive have live controls only. Walls
preserve camera watermarks, and suspend offscreen players and hidden tabs.
Remounting a player rechecks access, obtains the current user token and applies
the shared playback position. See video wall playback.
Group inheritance and the administrative Cameras page remain unchanged.
All UI timestamps are rendered in the browser timezone. The server stores and exchanges timestamps as absolute values.
| Streams and playback | Monitoring | ONVIF |
|---|---|---|
![]() |
![]() |
![]() |
| Dashboard | Mosaic | Map | Player |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| Mosaic | Map | Player |
|---|---|---|
![]() |
![]() |
![]() |
sudo bash scripts/install.sh \
--domain portal.example.com \
--email admin@example.com \
--admin-login admin \
--admin-password 'change-me-now'The installer creates an nginx site, connects the detected php-fpm socket,
initializes SQLite, creates the first admin user, and can issue a Let's Encrypt
certificate through certbot certonly --webroot. It writes only the
SesamePortal site file and does not let certbot rewrite existing nginx site
configs. It also installs /usr/local/sbin/sesame-portal-update and a sudoers
rule so an admin can update Portal from the web UI under Settings.
For repair/update runs against an existing database:
sudo bash scripts/install.sh \
--domain portal.example.com \
--email admin@example.com \
--repairThe installer backs up the current release, nginx site, cron entry, config, and SQLite files before applying changes. If a step fails, it restores those files and reloads nginx/php-fpm when possible.
Open the portal URL after installation:
https://portal.example.com
Use the credentials passed to the installer:
- login: the value of
--admin-login, defaultadmin; - password: the value of
--admin-password.
Example from the command above:
login: admin
password: change-me-now
During --repair runs, the installer does not change existing admin users when
--admin-password is omitted.
SesamePortal is normally connected to one or more SesameDVR servers. For GitHub evaluation installs, use this public SesameDVR trial key:
curl -fsSL https://license.sesameware.com/sesame-dvr-artifacts/bootstrap-trial-install.sh | sudo bash -s -- --license-key SDVR-TRIAL-85GT2-A7YYD-HSSEN-YW98UFor public HTTPS access, pass the target DVR domain and ACME email:
curl -fsSL https://license.sesameware.com/sesame-dvr-artifacts/bootstrap-trial-install.sh \
| sudo bash -s -- \
--license-key SDVR-TRIAL-85GT2-A7YYD-HSSEN-YW98U \
--publish-service \
--publish-server-name dvr.example.com \
--publish-acme \
--acme-email admin@example.comMore details are in
docs/SESAME-DVR-TRIAL-INSTALL.ru.md.
Additional SesameDVR documentation:
- SesameDVR feature and product description
- SesameDVR user guide
- SesameDVR HTTP API reference (RU)
- SesameDVR storage configuration (RU)
- SesameDVR Prometheus / OpenMetrics endpoint (RU)
- SesameDVR BEAM hot patch manifest (RU)
- SesameDVR DVR-side failover runbook (RU)
php bin/portal migrate
php bin/portal create-admin <login> <password>
php bin/portal rotate-tokens
php bin/portal rotate-secrets
php bin/portal backup /path/to/backup.json
php bin/portal restore /path/to/backup.jsonrotate-secrets re-encrypts stored SesameDVR management tokens with the
configured crypto_primary_key while preserving access to older key ids for
rotation windows.
app/Portal.php remains the shared bootstrap for the web application, CLI and
tests. Runtime classes live in individual files; App composes resource API,
page, Auth Backend, UI and support modules. See PHP module architecture
for ownership boundaries and release requirements.
find app -name '*.php' -exec php -l {} \;
php tests/module_bootstrap.php
bash -n scripts/install.sh
tests/http_smoke.sh
bash tests/release_smoke.sh








