01 Overview
Kelra Room is a software layer that turns any meeting-room touch panel — a Windows OPS module, a Huawei IdeaHub, a generic vendor display — into a unified room terminal: schedule, one-tap video-conference joining, and a collaborative whiteboard.
The product answers a simple problem: a fleet of meeting rooms is never homogeneous. Screens bought years apart, different brands, different remote controls. Every meeting starts with five minutes of troubleshooting. Kelra Room imposes the same interface, the same gestures and the same video call across the whole estate, whatever hardware sits underneath.
What an installation is made of
One screen per room
A standalone Windows application, full screen, with no visible browser. It shows the room, its schedule, and opens video calls. One executable to install, nothing else on the machine.
One central server
A Linux machine, on your premises. It queries the calendars, serves the admin console, relays the whiteboard in real time and holds the entire configuration.
Your calendars
Microsoft 365 (Exchange Online) and/or Google Workspace. Kelra Room reads your rooms' resource mailboxes — the very ones your staff already book.
Design principles
| Principle | What it means in practice |
|---|---|
| Self-reliance | Everything runs on your own infrastructure. No meeting content, no whiteboard, no minutes pass through a third-party service. The only outbound traffic goes to your own calendar providers. |
| Hardware independence | No proprietary hardware to buy. Kelra Room installs on the screens you already own, as long as they run Windows 10/11. |
| Minimal footprint | A single server service, an embedded database, no external dependency to install. Fifty rooms fit on a mini-PC. |
| Network resilience | Fonts and graphics are self-hosted: the kiosk depends on no CDN. If the server becomes unreachable, the screen keeps showing the last data it received, with a timestamp. |
| Ownership | A perpetual per-screen licence, with no mandatory subscription. The source code is provided and auditable. |
What Kelra Room does not do
To frame an evaluation properly, the scope limits are worth stating plainly:
- Kelra Room does not replace your video-conferencing platform. It detects the Teams, Meet or Zoom link in the invitation and opens it full screen — the meeting stays with its vendor.
- It does not drive the room's audio/video hardware (camera, soundbar, panel control). Those remain handled by their usual Windows drivers.
- It does not measure actual call duration: the statistics are based on the slots booked in the calendar (see Operations).
- The hosted multi-site admin console is a separate commercial option; a standard deployment administers each server individually.
02 Features
The full life of a meeting, from the schedule on the wall to the minutes emailed to attendees.
Room screen
The screen permanently shows the time, the room name, its status and the day's schedule. The status is readable from the corridor: green when the room is free, red when it is busy, with the time it frees up or the next booking.
| Item | Detail |
|---|---|
| Two layouts | Standard (meeting list plus action tiles) or Agenda (full-screen calendar). Chosen on the screen and remembered there. |
| Action tiles | Join the call · New whiteboard · Instant meeting · Calendar. Tiles that do not apply are hidden rather than greyed out. |
| Wallpapers | A 4K image library served by the server, with a shuffled slideshow mode, or the room theme's own background. Remembered per screen. |
| 8 languages | French, English, Polish, Spanish, Portuguese, Chinese, Romanian, Ukrainian. Picker in the bottom bar; otherwise the browser language decides. |
| Theme & logo | Six presets (blue, purple, green — dark or light) and your logo in place of Kelra Room's, set per room from the console. |
| Diagnostics panel | Reachable from the screen: IP address, gateway, server reachability, internet egress, the state of each calendar, a clock check, and the version of the screen and of the server. |
| Degraded mode | If the server is unreachable the screen keeps its display and states “Data from hh:mm” rather than emptying. An incomplete view — one of two calendars unreachable — is flagged as such. |
Joining a video call
Kelra Room parses the meeting invitation and extracts the call link, whatever the format — an Exchange HTML body, a Google description, a link pasted by hand. A large “Join the call” button appears as soon as a meeting starts.
Recognised platforms
Microsoft Teams · Zoom · Google Meet · Cisco Webex · Whereby · Jitsi Meet · Proton Meet · BlueJeans · GoTo Meeting · RingCentral · Livestorm.
A generic fallback recognises meeting links from platforms that are not listed — a large account's in-house tool, a regional product. It is deliberately conservative: better no button at all than one that opens the organiser's privacy policy.
The call opens in a real browser
When someone taps “Join”, the application launches Microsoft Edge full screen, in a dedicated, isolated profile. That choice is imposed by the platforms themselves: Google and Microsoft refuse participation from a browser embedded inside an application. Edge ships with Windows — nothing to install.
During the call a floating bar stays above every window, movable, translated into the screen's language. It carries two deliberately separate actions:
- “Back to kiosk” — brings the room screen to the front without touching the meeting, which carries on behind, audio and camera included. That is what lets you open the whiteboard mid-session and then return to the call: the button then reads “Back to the call”.
- “Leave the call” — actually ends the meeting and returns to the room screen. Different colour, different area: it is the only one of the two that cuts the call.
Closing the window by hand triggers the same cleanup: no window and no process piles up from one meeting to the next.
Two identity modes in meetings
| Guest default | Room account | |
|---|---|---|
| Tenant-side configuration | none | interactive sign-in + Teams Rooms licence |
| Displayed identity | “Guest” | the room name |
| Lobby | per the organiser's policy | bypassed for internal meetings |
| Instant meeting | unavailable | available |
| Directory, calling a colleague | no | yes |
The mode is set per room in the console. The room account is signed in once, at installation, from the screen itself; the session is kept in the call profile.
Instant meeting
One tap creates a Teams or Google Meet meeting on the fly in the room's calendar, books the room for an hour and opens the call. Available only in “room account” mode: an anonymous participant would have neither a directory nor any way to invite anyone, and the room could end up stuck in its own lobby.
Collaborative whiteboard
A full-screen whiteboard, shared in real time, opened from the room screen in one gesture. Excalidraw engine, scene relay hosted on your own server.
Join by QR code
A QR code in the corner of the board opens the session on anyone's phone or laptop. No application to install, no account to create.
PDF minutes
The board is exported at high resolution, assembled into a PDF, then downloaded or emailed to every meeting attendee in one gesture.
Sending the link
During a call, remote attendees cannot scan the QR code shown in the room: a button emails them the board link instead.
Closing by the host
The room screen hosts the session. It closes the board at the end of the meeting: guests see a closing message and the scene stops being reachable.
The Windows application puts a relay in front of its own service: a guest's phone only ever talks to the room screen, on the local network, and the screen talks to the server. A central server behind a VPN therefore stays usable from a phone sitting in the room, without exposing the admin console to the guest network.
Multi-tenant broker — booking arbitration
The use case: a building shared by two organisations, one on Microsoft 365, the other on Google Workspace. Both want to book the same physical room, each from its own resource calendar. Without arbitration both accept — and two meetings turn up at the same time.
The Kelra Room broker aggregates the calendars of every organisation linked to a room and arbitrates pending invitations:
- First come, first served — invitations are processed in the order they arrive.
- Slot free across every calendar → the invitation is accepted and the organiser gets the usual confirmation.
- Conflict with an already-accepted booking, including one in the other organisation → the invitation is declined with a reason, visible to the organiser in the response.
Busy mirrors
A refusal arrives after the fact: until then, Outlook's Room Finder and Google's room picker show the room as free — they only read their own calendar. As soon as a booking is accepted, Kelra Room therefore places a neutral busy event on the room's other calendars, titled “Booked — another organisation”. The room shows as busy in the tool the user actually looks at, before any attempt.
- The subject and the organiser never cross the boundary between organisations. The mirror carries only a neutral title, which you choose.
- Mirrors are reconciled on every pass: booking moved → mirror moved; cancelled → mirror removed.
- They do not appear on the room screen, which already shows the original meeting, but they are visible and labelled in the console.
- The mechanism can be switched off; arbitration still declines conflicts regardless.
Admin console
A web interface served by the server, reachable from any machine on the permitted network. Nine tabs:
| Tab | Contents |
|---|---|
| Overview | Deployment status, rooms and screens at a glance, server version. |
| Rooms | Creation and editing: name, description, resource calendar address, organisation, theme, logo, join mode. |
| Devices | The provisioned screens, their room, their key, their last contact. Deleting one revokes it immediately. |
| Organisations | Microsoft 365 and Google Workspace connections, with credentials verified on save. |
| Broker | Room ↔ organisation links, manual synchronisation, and a log of arbitration decisions with their reasons. |
| Accounts | Named administrator accounts. All of them have full access. |
| Audit log | Ninety days of change actions and sign-in attempts, attributed to their author. |
| Statistics | Usage over 7, 30 or 90 days: meetings held, average duration, attendees, hours occupied, split by room and by platform. |
| Licence | Customer, seats used and available, expiry, key activation and removal. |
Console language: French and English. The room screen speaks eight — it is seen by your visitors, whereas the console is only seen by your IT teams.
03 Architecture
One central server, one screen per room, and the attendees' own devices joining the whiteboard. Nothing else.
The server
A single service, delivered as a container, gathering four roles:
| Role | Description |
|---|---|
| Screen API | Room schedule, room details, instant meeting, PDF export. Authenticated by a key unique to each screen. |
| Admin console | A complete web interface, authenticated by named account. |
| Real-time relay | Broadcasts whiteboards between the participants of a session, resynchronising latecomers. |
| Calendar connectors | Reads Microsoft 365 and Google Workspace resource mailboxes, merges the views, runs the broker's arbitration. |
All persistent data — rooms, screens, organisations, licence, arbitrated bookings, logos — fits in a single volume: an embedded database and a folder of files. There is no external database server to install, back up or upgrade.
The room screen
A single Windows executable carrying everything it needs. It installs per machine — necessary, since in Windows kiosk mode the screen runs under a dedicated account, separate from the technician who installs it. Three locations on the machine survive an uninstall: the server address, the wallpaper library, and the screen's identification key. An upgrade therefore never forces you to re-provision the room.
Authentication, in short
| Link | Mechanism |
|---|---|
| Screen → server | A device key, obtained by scanning a QR code at provisioning, stored on the machine and never carried in a configuration file. Revocable at any moment from the console. |
| Administrator → server | A named account (username + password), with a password change forced on first access and an attributed audit log. |
| Server → Google Workspace | OAuth 2.0 with a refresh token; the access token is renewed automatically. |
| Server → Microsoft 365 | Application-level client credentials flow — no user needs to sign in. The token renews automatically every hour. |
| Attendees → whiteboard | A session link, delivered by QR code or by email. No account, no application. |
04 Requirements
What must be in place before installation, on the server, on the screen and on the network.
Server
| Component | Minimum version | Notes |
|---|---|---|
| Linux | Ubuntu 22.04 LTS or Debian 12 | Any distribution with a stable container engine will do. |
| Container engine | Docker Engine 24+ | The engine alone is enough; no desktop edition is required or recommended. |
| Compose | v2 (plugin) | Shipped with current Docker packages. |
Room screen
| Component | Required |
|---|---|
| Windows 10 or 11 | On the OPS module or the room PC. The Enterprise, Education or IoT Enterprise editions are recommended for fully locking down the machine (see Screen installation). |
| Microsoft Edge | For video calls. Ships with Windows. Failing that, the default browser is used, without forced full screen. |
| Nothing else | The standalone application carries its own service and runtime. No extra software prerequisite, no virtualisation layer. |
Calendars
- A resource mailbox (room account) per physical room, in Microsoft 365 and/or Google Workspace — the one your staff already book.
- For Microsoft: an application registration in your directory, with admin consent. For Google: a Cloud project with the Calendar API enabled.
- For the instant meeting: a licence including Teams on the room mailbox (Teams Rooms Basic, free up to 25 rooms, is enough) or the Google Meet API enabled.
Network
| Constraint | Detail |
|---|---|
| Port to open | TCP 4001 to the server, from the screens and the administration workstations. |
| Server egress | HTTPS 443 to graph.microsoft.com and googleapis.com to read the calendars. |
| Reachability | The screens must reach the server: same LAN, corporate VPN, or a public name with TLS. |
| TLS | Recommended. The server's built-in local authority, a corporate certificate, or a reverse proxy. See Encryption. |
| SMTP | Optional — port 587 or 465 to your relay, for sending the minutes. |
The complete matrix, flow by flow, is in chapter 6.
05 Server sizing
Four tiers, from a pilot site to a 500-screen estate. The sizing is deliberately generous: the real footprint is lighter.
Tier 1 — up to 50 screens
Pilot deployment, single office.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU | 2 vCPU |
| RAM | 2 GB | 4 GB |
| Storage | 20 GB SSD | 40 GB SSD |
| Network | 10 Mbps | 100 Mbps |
Estimated load: ~1 request/s, 50 active real-time connections. An entry-level VPS or a local mini-PC is perfectly adequate.
Tier 2 — 50 to 150 screens
Single site, or a modest multi-site setup.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| RAM | 4 GB | 8 GB |
| Storage | 40 GB SSD | 80 GB SSD |
| Network | 100 Mbps | 100 Mbps |
Estimated load: 3 to 5 requests/s, 150 real-time connections, broker arbitration every 60 s. A standard VPS is ideal.
Tier 3 — 150 to 300 screens
A campus, or busy multi-site.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 vCPU | 8 vCPU |
| RAM | 8 GB | 16 GB |
| Storage | 80 GB NVMe SSD | 150 GB NVMe SSD |
| Network | 100 Mbps | 1 Gbps |
Estimated load: 5 to 10 requests/s, 300 real-time connections, broker across several organisations. A dedicated server or a CPU-optimised VPS is recommended, with automated daily backups.
Tier 4 — 300 to 500 screens
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 8 vCPU | 16 vCPU |
| RAM | 16 GB | 32 GB |
| Storage | 150 GB NVMe SSD | 300 GB NVMe SSD (RAID-1) |
| Network | 1 Gbps | 1 Gbps |
Estimated load at 450 screens: ~15 requests/s sustained, 450 permanent real-time connections, and a broker potentially covering dozens of multi-organisation rooms. RAM is the main sizing factor.
Additional recommendations at this tier:
- A dedicated server (bare metal or a compute-optimised cloud instance) rather than a shared VPS.
- Automated daily off-site backup — a single volume holds the entire state.
- Availability monitoring on the
/healthendpoint. - TLS mandatory.
- A UPS, or automatic service restart (already configured by default).
Summary
| Tier | Screens | CPU | RAM | Storage | Profile |
|---|---|---|---|---|---|
| Starter | < 50 | 2 vCPU | 2–4 GB | 20–40 GB | Entry-level VPS / mini-PC |
| Standard | 50–150 | 2–4 vCPU | 4–8 GB | 40–80 GB | Standard VPS |
| Pro | 150–300 | 4–8 vCPU | 8–16 GB | 80–150 GB | Dedicated or CPU-optimised VPS |
| Enterprise | 300–500 | 8–16 vCPU | 16–32 GB | 150–300 GB NVMe | Dedicated or cloud compute |
The server footprint is intentionally light: an embedded database, a single container, zero third-party dependencies to install. The sizing above is deliberately generous — in practice several hundred simultaneous connections run comfortably on modest hardware.
06 Network flow matrix
Every flow, source by destination — hand this table straight to your network or security team.
| Symbol | Direction |
|---|---|
| → | Outbound flow — the source opens the connection |
| ↔ | Persistent two-way flow (WebSocket) |
1 · Screens → Server (internal network)
| Port | Proto | Direction | Purpose | Frequency | Required |
|---|---|---|---|---|---|
| 4001 | TCP / HTTP(S) | → | Connectivity check | ~10 s | Yes |
| 4001 | TCP / HTTP(S) | → | Server version | At startup | Yes |
| 4001 | TCP / HTTP(S) | → | Device key verification | At startup | Yes |
| 4001 | TCP / HTTP(S) | → | Room schedule poll | ~30 s | Yes |
| 4001 | TCP / WS(S) | ↔ | Room real-time channel | Persistent | Yes |
| 4001 | TCP / WS(S) | ↔ | Collaborative whiteboard | When opened | Yes |
| 4001 | TCP / HTTP(S) | → | Instant meeting creation | On demand | Yes |
| 4001 | TCP / HTTP(S) | → | PDF minutes | End of meeting | Optional |
| 4001 | TCP / HTTP(S) | → | Emailing the whiteboard link | On demand | Optional |
2 · Admin workstation → Server (internal network)
| Port | Proto | Direction | Purpose | Frequency | Required |
|---|---|---|---|---|---|
| 4001 | TCP / HTTP(S) | → | Loading the console | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Authentication | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Room management | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Device management | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Organisation management | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Audit log | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Multi-organisation arbitration | Session | Optional |
| 4001 | TCP / HTTP(S) | → | Licence management | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Usage statistics | Session | Yes |
| 4001 | TCP / HTTP(S) | → | Deployment health report | Session | Yes |
3 · Provisioning & whiteboard (internal network)
| Source | Port | Proto | Direction | Purpose | Frequency | Required |
|---|---|---|---|---|---|---|
| Technician phone / laptop | 4001 | TCP / HTTP(S) | → | Provisioning QR scan | Per enrolment | Yes |
| Technician phone / laptop | 4001 | TCP / HTTP(S) | → | Room ↔ screen pairing | Per enrolment | Yes |
| Attendees | 4001 | TCP / HTTP(S) | → | Whiteboard page | When invited | Optional |
| Attendees | 4001 | TCP / WS(S) | ↔ | Whiteboard collaboration | During the meeting | Optional |
Attendees connect to the server — directly, or through the room screen's relay — and never to a third-party service. One port to open: 4001.
4 · Server → Calendar providers (outbound internet)
| Destination | Port | Proto | Direction | Purpose | Frequency | Required |
|---|---|---|---|---|---|---|
oauth2.googleapis.com | 443 | TCP / HTTPS | → | Google access-token refresh | ~1 h | If Google |
www.googleapis.com | 443 | TCP / HTTPS | → | Reading the room schedule | Every poll | If Google |
meet.googleapis.com | 443 | TCP / HTTPS | → | Creating an instant Meet meeting | On demand | If instant meetings |
login.microsoftonline.com | 443 | TCP / HTTPS | → | Application token acquisition | ~1 h | If Microsoft |
graph.microsoft.com | 443 | TCP / HTTPS | → | Reading the Exchange schedule | Every poll | If Microsoft |
graph.microsoft.com | 443 | TCP / HTTPS | → | Creating an instant Teams meeting | On demand | If instant meetings |
graph.microsoft.com | 443 | TCP / HTTPS | → | Invitation replies (arbitration) and busy mirrors | 60 s (configurable) | If broker |
4 bis · When that outbound path goes through a proxy
On a closed network the flows above do not leave directly: they cross a corporate proxy, sometimes paired with TLS inspection. Two points decide whether the installation succeeds, and neither is guessable.
Declare the proxy in the environment: block of the server service — not in the .env file alone, whose contents never reach the container:
environment:
HTTPS_PROXY: http://proxy.company.local:8080
HTTP_PROXY: http://proxy.company.local:8080
NO_PROXY: localhost,127.0.0.1,10.0.0.0/8
The server tunnels every request through CONNECT on 443, including those aimed at http:// URLs. A proxy that only relays cleartext HTTP will not do: its allowlist must name login.microsoftonline.com, graph.microsoft.com, oauth2.googleapis.com and www.googleapis.com.
Behind TLS inspection (Zscaler, Netskope, Fortinet…), the appliance presents a certificate signed by an internal authority. The server must be given that authority — mount the file, then point to its path inside the container:
volumes:
- /etc/ssl/certs/company-ca.crt:/app/company-ca.crt:ro
environment:
NODE_EXTRA_CA_CERTS: /app/company-ca.crt
Turning certificate verification off instead would expose the traffic — calendar tokens included — to anyone on the path. Kelra Room offers no such setting.
5 · Server → SMTP relay (outbound)
| Destination | Port | Proto | Direction | Purpose | Frequency | Required |
|---|---|---|---|---|---|---|
| Customer SMTP relay | 587 | TCP / STARTTLS | → | PDF minutes and whiteboard links | On demand | Optional |
| Customer SMTP relay | 465 | TCP / TLS | → | Same, implicit-TLS variant | On demand | Optional |
6 · Screens → Video-conferencing platforms (outbound internet)
These flows leave from the room screen's network, through the browser, and never from the server.
| Destination | Port | Proto | Direction | Purpose |
|---|---|---|---|---|
meet.google.com | 443 | TCP / HTTPS | → | Google Meet interface |
| Google STUN/TURN servers | 443 / 19302 | TCP + UDP | ↔ | Google Meet WebRTC media |
teams.microsoft.com | 443 | TCP / HTTPS | → | Microsoft Teams interface |
| Microsoft Teams media servers | 443 / 3478-3481 | TCP + UDP | ↔ | Teams WebRTC media |
zoom.us | 443 | TCP / HTTPS | → | Zoom interface |
| Zoom media servers | 443 / 8801-8802 | TCP + UDP | ↔ | Zoom media |
Microsoft publishes the exhaustive list of its Teams address ranges and ports at aka.ms/ipurlsplan. Fold it into your filtering policy if the screens sit behind a proxy or an application firewall. The same applies to the ranges published by Google and Zoom.
Firewall rules at a glance
| Rule | Destination | Port | Direction | Priority |
|---|---|---|---|---|
| Screens → server | Kelra Room server | TCP 4001 | Inbound to server | Mandatory |
| Admins → server | Kelra Room server | TCP 4001 | Inbound to server | Mandatory |
| Server → Google | *.googleapis.com, *.google.com | TCP 443 | Outbound from server | If Google |
| Server → Microsoft | login.microsoftonline.com, graph.microsoft.com | TCP 443 | Outbound from server | If Microsoft 365 |
| Server → SMTP | SMTP relay | TCP 587 or 465 | Outbound from server | Optional |
| Screens → video | Internet (Meet / Teams / Zoom…) | TCP 443 + UDP media | Outbound from screens | Mandatory for calls |
07 Installation
Allow half a day for the server and the first room, then about ten minutes per additional room.
Server
The server ships as a deployment bundle containing the service image and its orchestration file. Bringing it up takes three steps:
- Drop the bundle on the Linux machine and fill in the
.envconfiguration file — at minimum a long, random administration secret. - Start the service. It restarts automatically when the machine reboots.
Start-up
docker compose up server -d - Check it. The API answers on
http://<SERVER_IP>:4001, the console onhttp://<SERVER_IP>:4001/admin. The/healthendpoint returns the exact version deployed.
Port 4001 is the one published on the host machine. If it is already taken, change it in the orchestration file — nothing needs rebuilding. Remember to carry the new port over into the address entered on the screens.
Encrypting the traffic (TLS)
The server can serve the console and the API over https with no extra component. Three modes, chosen in the .env file:
| Mode | Setting | Use |
|---|---|---|
| Cleartext | default, nothing to declare | The server listens on http. Acceptable on a controlled corporate LAN. |
| Local authority | TLS_SELF_SIGNED=1 + TLS_NAMES | The server creates its own certificate authority and its certificate on first start. No public domain, no internet access required. |
| Supplied certificate | TLS_CERT_PATH + TLS_KEY_PATH | Your own certificate, issued by your corporate PKI or by a public authority. |
The local authority, in practice
TLS_NAMES lists the names and addresses the server will be reached by — for example 192.168.1.10,rooms.internal,localhost. They are written into the certificate: an address missing from that list will be refused by the browser. The authority created stays stable and survives renewal of the server certificate: screens already deployed need no further action.
- Admin workstations — the authority is downloaded from
/tls/ca.crtand installed once into the machine's or the domain's certificate store. The console is then served without any warning. - Room screens — the Windows application fetches the authority on first contact with the server and pins it. It then refuses any different authority: a server swapped in later is rejected, not silently accepted. The fingerprint is printed in the server's start-up banner and logged by the application at the moment it pins — comparing them once is your verification.
A screen served over https that called an http server would have its requests blocked by the browser. The two switch together: settling it before enrolment saves a second visit to every room.
If the kiosk address was left on http
This is the most common oversight after a switchover. An address left on http:// against a server listening over HTTPS made the screen unusable with nothing naming the cause: the QR code link landed on a 404 — often the corporate proxy's, which therefore appeared to blame the application — and the screen's countdown kept running while the console answered "Link expired".
Three safety nets now catch the oversight. They do not replace fixing it.
- The kiosk corrects the address by itself. It asks the server at startup, then again from the screen's own browser, and uses the scheme the server actually serves. The correction applies to the current session and is not saved.
- The screen says so, and the log repeats it. A banner announces the correction;
docker compose logs kioskgives the configured address, the one in use, and the variable to fix. FixingOPENROOM_SERVER_URLis still required — otherwise the mismatch returns at the next deployment. - The server names the failure. A cleartext request on an HTTPS port produces no reply at all: the handshake fails before the application exists, and no redirect can be sent.
docker compose logs servernow carries a[tls] ⚠ une requête en CLAIR est arrivée sur ce portline.
If the screen has already pinned another server's authority — a screen that moved, a server that was reinstalled — it refuses the new one. The refusal is deliberate and will not change: silently accepting a different authority would cancel out the benefit of encryption.
Up to 1.0.5 that refusal showed as "Server unreachable" and sent people looking for a network fault that did not exist. From 1.0.6 on, the screen shows "Server certificate refused", both fingerprints — the one it pinned, the one the server presents — and the "Change the server address" button, which clears the address and the pinning, then restarts.
Comparing the presented fingerprint with the one the server logs at startup ([tls] empreinte de l'autorité) settles it: if they match, the server really was reinstalled and clearing is legitimate; if they differ, the screen is not talking to the server you think it is.
It only counts down once the token is registered on the server. A --:-- display with "Waiting for the server" means the screen cannot reach the server — not that the link is still valid. It is the first place to look.
Behind a reverse proxy that terminates TLS (Caddy, Traefik, Tailscale), the server listens in cleartext while its clients speak HTTPS. It then follows the x-forwarded-proto header, which those proxies set by default, and correctly announces https://. The header is consulted only when the server does not encrypt the traffic itself: no forged request can make an encrypted server announce a cleartext URL.
The other routes
Encrypted private network
On a distributed estate: if your machines already sit on a private mesh such as Tailscale, the certificate comes with it and the server becomes reachable under a stable name, with no internet exposure.
Public reverse proxy
An automatic-certificate proxy (Caddy, Traefik) in front of the server. Requires a resolvable domain name and port 443 reachable for certificate validation.
Room screen
A single Windows installer, supplied by Kelra. It bundles the application, its service and its runtime: nothing else to install on the machine, no virtualisation layer.
What the installer does
- A per-machine install, into
Program Files— elevation is requested once. It is necessary: in kiosk mode the screen runs under a dedicated account, separate from the technician's. - On first launch the application registers itself to start at logon. This can be disabled if you drive start-up through a Windows policy.
- The application is already full screen, with no address bar and no tabs.
First launch
- Enter the server address on the first-launch screen, by touch. A “Test connection” button validates the address; saving is only possible after a successful test, and only once — an address that could be changed at any time would let any machine on the network redirect the screen to a server it controls.
- Provision the screen: it then shows a QR code, valid for 5 minutes and refreshed automatically. Scan it with a phone — or open the URL printed underneath from a machine that can reach the server — pick the room from the list and confirm. The screen configures itself within seconds.
- Set the machine's clock and time zone — see the box below.
The times displayed are computed from the clock and time zone of the screen's own Windows system. An OPS module fresh from the factory is often left on a default time zone: the screen then shows slots several hours out, and nobody thinks to blame the clock. The kiosk's diagnostics panel continuously compares the screen's time with the server's and flags any drift over two minutes.
Locking Windows down on top
The application is already locked full screen. Windows kiosk mode adds only three things: preventing escape to the desktop, restarting the application if it closes, and barring other programs.
| Windows edition | What is possible |
|---|---|
| Enterprise / Education / IoT Enterprise | Shell Launcher: the application replaces Windows Explorer. The most complete lockdown, and the recommended configuration. |
| Pro | Shell Launcher is unavailable. Two fallbacks: automatic logon to a dedicated account that launches the application (the simplest, and enough since the window is already locked), or assigned access's restricted user experience, which leaves a limited desktop rather than a true shell. |
A diagnostic script shipped with the product answers, in one pass, every question about the edition, the Edge version and the policies that apply on the machine.
Silencing the browser's prompts
Do this once per machine. A room screen must ask for nothing: you press “Join” and you are in the meeting. The application already prepares the video-call profile at every launch — translation off, notifications and geolocation blocked, camera and microphone granted upfront to the known platforms, first-run banners dismissed.
One dialog remains that only an enterprise policy can remove: “This site is trying to open Microsoft Teams”. The Teams web page tries to launch the desktop application, which has no business being installed on a room screen. An Edge policy blocking the msteams:, msteams-enterprise:, zoommtg: and zoomus: protocols removes it silently — the exact procedure ships with the product.
That policy applies to every instance of the browser, not just ours. An application that rewrote browser policy at start-up, without the operator knowing, would be a bad neighbour on a managed machine. It is an installation step, and we own it as such.
What remains: Teams shows its own page — “How do you want to join your meeting?” — with a “Continue on this browser” button. That is not a browser dialog but the content of Microsoft's page, and no policy reaches it. One tap is therefore still needed for Teams meetings. URL parameters that bypass it circulate, but Microsoft does not document them: hard-wiring those would make meetings open, across an entire estate, on behaviour that can change without notice.
Addresses used by the QR codes
Shared URLs — the whiteboard QR, the provisioning QR — must never contain localhost. The screen detects its local address automatically, discarding virtual adapters. If detection picks the wrong interface, the address can be forced through configuration. Remember to allow the relevant ports in the Windows firewall, or attendees who scan the QR will not reach the whiteboard.
08 Configuration
Everything is set from the admin console, except the prerequisites to create at Microsoft and Google.
Console and accounts
The console opens at http://<SERVER_IP>:4001/admin.
- First sign-in — on first start the server creates an
admin/adminaccount. A password change is enforced straight away, and until it is done the whole API refuses to answer. A well-known default credential pair is the first thing bots try; the lock exists so that a forgotten deployment does not stay open. - Named accounts — Accounts tab: one account per administrator. All have full access; to separate several entities, deploy one instance per entity rather than sharing this one.
- Connect an organisation — Organisations tab: Microsoft 365 and/or Google Workspace (next sections).
- Create the rooms — Rooms tab: name, description, resource calendar address (e.g.
room-a@mycompany.com), organisation, theme, logo. - Provision the screens — by QR code from each screen, or by creating the device by hand in the Devices tab.
The Log tab keeps 90 days of modification actions and sign-in attempts, attributed to their author. Its entries stay in French: they are composed at write time and stored as such — a log should read exactly as it was written, not be re-translated after the fact.
There is no “forgotten password” email on a self-hosted installation. The remedy is a reset command run from the server machine, documented in the operations guide supplied. Keep the administration secret set at install time in your corporate vault.
Some browsers — Brave in particular — block requests to private IP addresses by default. For the console, prefer Firefox, Edge or Chrome.
Connecting Google Workspace
On the Google Cloud side
- Create a project — or reuse one — in the Google Cloud console.
- Enable the Google Calendar API. For instant meetings, also enable the Google Meet API.
- Create OAuth 2.0 credentials of the “Web application” type and note the client ID and client secret.
- Obtain a refresh token using the account that has access to the resource calendars. The scopes needed: calendar read, plus Meet space creation if instant meetings are wanted. For multi-organisation arbitration, the full calendar write scope is required.
On the Kelra Room side
Organisations tab → New organisation:
| Field | Value |
|---|---|
| Provider | |
| Organisation name | Your company |
| Domain | mycompany.com |
| Client ID / Client secret | From the Google Cloud console |
| Refresh token | Obtained in the previous step |
“Verify and save” genuinely tests the credentials before accepting them. The refresh token stays valid until access is revoked; the access token is renewed automatically.
Connecting Microsoft 365
On the Azure / Entra ID side
- Register an application — App registrations → New registration. Accounts in this organisational directory only; no redirect URI. Note the tenant ID and the application ID.
- Choose the authentication method — two options, identical in operation. Client secret: Certificates & secrets → 24-month lifetime → copy the secret's value (not its ID). Certificate: upload a public certificate under the Certificates tab of the same page. The certificate is the recommended option, and becomes mandatory where internal policy forbids client secrets.
- Grant the
Calendars.ReadWritepermission of type Application on Microsoft Graph, then click Grant admin consent. That single permission covers schedule display, instant meetings and arbitration. The read-only permission would display the calendar but make meeting creation fail.
These permissions are of the Application type, not delegated: no user needs to sign in, and no user session is stored. The room's mailbox must hold a licence that includes Teams for created meetings to carry a video link.
Certificate authentication — no shared secret
Many organisations forbid client secrets by policy: a secret is a long-lived string, copied into a configuration file, that nothing distinguishes in an audit log. With a certificate, Kelra Room signs a short-lived token using a private key that never leaves your server; only the public half is deposited in Entra.
Entra does not validate the trust chain of an application authentication certificate: it stores the public key and locates the certificate by its thumbprint. A self-signed certificate is therefore a nominal case, and a certificate issued by your internal PKI works just as well — with the added benefit of your existing governance: inventory, expiry alerts, revocation.
Without a PKI, the utility ships inside the server image:
docker compose exec server node scripts/generer-certificat-entra.mjs kelra-room 2
It produces a .cer — the public certificate, to be uploaded to Entra — and a .key, the private key, to be entered in the admin console and shared with nobody. The thumbprint it prints must match the one the Azure portal shows after upload.
Two constraints imposed by Entra, not by Kelra Room: the key must be RSA, 2048 bits or more — ECDSA certificates are rejected, even though a modern PKI profile often issues them by default — and it must carry no passphrase, since the server starts without human intervention. The console reports both cases on save, along with a certificate and key that do not form a pair.
This certificate is unrelated to the TLS certificate that encrypts traffic between the displays and the server. This one authenticates the application to Microsoft; the other protects the transport. They coexist without knowing about each other.
Optional — letting external attendees in
By default Teams puts attendees from outside your directory in the lobby — and nobody is signed in on the screen to admit them. To open the lobby automatically on instant meetings, an extra permission (OnlineMeetings.ReadWrite.All) and a Teams Application Access Policy are needed. Without that configuration instant meetings still work: internal attendees walk straight in, only external ones have to be admitted.
On the Kelra Room side
| Field | Value |
|---|---|
| Provider | Microsoft |
| Organisation name | Your company |
| Tenant ID | Directory (tenant) ID |
| Client ID | Application (client) ID |
| Client secret | The value of the secret you created |
Multi-organisation broker
By default a resource calendar auto-accepts invitations, before Kelra Room has had a chance to arbitrate. That behaviour must be turned off on every resource calendar wired to the broker — in Exchange Online for Microsoft, in the resource settings for Google Workspace. Invitations must stay pending until the broker has answered. If auto-accept stays on, everything appears to work but cross-organisation conflicts are never declined.
Permissions
| Provider | Permission | Note |
|---|---|---|
| Microsoft | Calendars.ReadWrite (Application) | Already granted in the previous step: nothing to add. Used to answer invitations and to post the busy mirrors. |
| Calendar write scope | The read-only scope is not enough. The account must also hold the “Make changes to events” right on the resource calendar. |
Wiring a room to its organisations
- Broker tab → Link a calendar: pick the room, the organisation, and enter the resource mailbox address within that organisation. Each organisation has its own for the same physical room.
- Repeat for the second organisation. As long as a room has only one calendar linked, the broker has nothing to arbitrate and says so.
- Synchronise forces an immediate poll and reports the bookings seen, the decisions taken and the errors met.
- Bookings unfolds what the broker saw and decided for that room: accepted, declined with the reason and the competing organisation, pending, cancelled.
A room accepts only one connection per organisation, and a resource calendar can be linked to only one room within the same organisation — the console explicitly refuses duplicates, which would make arbitration self-contradictory.
Broker settings
| Setting | Default | Description |
|---|---|---|
| Arbitration interval | 60 s | How often pending invitations are polled. The mechanism only runs if at least one room has broker connections — no cost at all while the feature is unused. |
| Busy mirrors | enabled | Posts a neutral busy event on the room's other calendars. Can be turned off; arbitration stays active. |
| Mirror title | “Booked — other organisation” | As seen by the other organisation's users. Never put the real subject in it: that subject belongs to the other organisation. |
Mirrors shrink the window during which the room still looks free to the second requester, without closing it completely: it lasts at most one arbitration cycle. A booking raised on the second organisation within that interval still gets a reasoned refusal.
Synchronisation covers a window from 1 day back to 60 days ahead. Removing a connection cleans up its mirrors before deleting it.
Email sending and PDF export
Downloading the PDF works with no configuration. Sending it by email requires an SMTP relay, declared on the server side:
| Setting | Role |
|---|---|
| SMTP host | Required to enable sending. Without it the screen says “SMTP not configured” and direct download remains available. |
| Port | 587 by default (STARTTLS), or 465 for implicit TLS. |
| Credentials | The relay's username and password. |
| From address | The address attendees will see on the emails sent to them. |
SMTP serves two purposes: sending the PDF minutes at the end of a meeting, and sending the whiteboard link to attendees — useful during a video call, when remote participants cannot scan the QR code displayed in the room.
The screen's diagnostics panel tests the SMTP configuration — connection and authentication, without sending a message. A positive result proves the relay accepts the connection and the credentials, not that the message will be delivered: relay refusals, spam classification and quotas only show up in real use.
Screen appearance
| Setting | Where | Detail |
|---|---|---|
| Theme | Console, per room | Six presets: blue, purple and green, in dark or light. |
| Logo | Console, per room | A PNG or SVG file up to 2 MB, replacing the Kelra Room logo in the header. |
| Wallpaper | On the screen | An image library served by the server, or a shuffled slideshow. The choice is remembered on the screen. |
| Layout | On the screen | Standard or Agenda. |
| Language | On the screen | Eight languages, picker in the bottom bar. |
| Join mode | Console, per room | Guest or room account — see Joining a call. |
Appearance changes take effect the next time the screen loads.
09 Operations
Backup, updates, monitoring and usage statistics.
Backup
The server's entire state lives in a single volume: the database — rooms, screens, organisations, licence, arbitrated bookings — and the uploaded logos. Backing up that volume is enough.
Two things are not in it and must be backed up separately: the .env configuration file — organisation secrets, administration secret, SMTP — and your wallpaper library.
The database uses no write-ahead log: a cold copy, with the service stopped for a few seconds, is clean and sufficient. Schedule a daily backup outside meeting hours. A hot copy works in the vast majority of cases but may catch a write in progress — acceptable as a safety net, never for a migration.
Migrating to another server
Restoring the archive on the new machine and copying the configuration across is enough. The licence keeps working: it is stored in the database and tied to no hardware. The trial-period anchor is preserved too — restoring a backup does not hand back another 30 days. Remember to update the server address on the screens if it changes.
Updates
A supplied update script fetches the new version, rebuilds the image and restarts the service. It refuses to run if a file affecting the deployment has been modified locally, rather than overwriting it silently.
Never edit a product file on a deployment machine. Everything that has to vary from one machine to another belongs outside the product: settings, secrets and addresses in the .env file; ports, volumes and options in a dedicated override file. Both survive every update.
On the screen side, updating means reinstalling the supplied executable. The server address, the device key and the wallpapers survive reinstallation: an update never forces you to re-provision a room.
Knowing what is running
The version and the build fingerprint are visible in five places: the server's start-up banner, the /health endpoint, the console sidebar (including before sign-in), the screen's diagnostics panel — which shows both versions, its own and that of the server it queries — and the Windows application log. An up-to-date screen talking to a stale server is therefore obvious immediately.
Monitoring
The /health endpoint is public and unauthenticated: it plugs straight into your monitoring stack (Uptime Kuma, Grafana, Zabbix…). It returns the service state, its version and its build fingerprint.
Usage statistics
Statistics tab, over 7, 30 or 90 days: meetings held, average duration, average attendance, hours occupied, and the split by day, by room and by video-conferencing platform.
Durations are the ones booked in the calendar, not the real length of the calls: the video conference opens in a separate browser the server does not see.
Only finished meetings are counted — the screens poll a rolling 24-hour window, which also contains meetings still to come.
History starts when the collector was commissioned, not when the server was installed. The tab shows the collection start date and flags any window that reaches back beyond it.
The figures cover this deployment. A multi-site customer running one server per site has no consolidated view — that is what the hosted admin console, offered as an option, is for.
10 Security & data
What is stored, where, and what never leaves your network.
Where the data lives
| Data | Location | Leaves your network? |
|---|---|---|
| Room and screen configuration | Server database | No |
| Whiteboard content | Server memory, for the duration of the session | No |
| PDF minutes | Generated on the fly, sent through your SMTP relay | No — other than through your own relay |
| Calendar access credentials | Server database | No — used only towards Microsoft and Google |
| Room schedules | Read on demand, never archived | No |
| Usage statistics | Server database, aggregated | No |
| Audit log | Server database, rolling 90 days | No |
No telemetry is emitted towards Kelra. A deployment with no internet connection works — except that it obviously cannot read a hosted calendar or open a video conference.
Access controls
- Screens — a unique device key, obtained by QR code, never written into a configuration file nor into the code served to the browser. Revocable instantly from the console: the screen then falls back to its provisioning screen.
- Administrators — named accounts, an enforced password change on first access, and an audit log attributed to each author.
- Whiteboard participants — access by session link; the room screen's relay forwards only the routes strictly needed by the whiteboard, and the admin console stays out of reach of the guest network. Every refused route is logged.
- First-launch screen — the server address can be saved only once, and only after a successful connection test, so that no machine on the network can redirect a screen to a server it controls.
On what crosses the boundary between organisations
In a multi-organisation deployment, only the fact that a slot is busy crosses the boundary. The meeting subject, the organiser and the attendee list are never replicated: the mirror posted on the other calendar carries nothing but a neutral title, which you choose.
Third-party components
Kelra Room embeds open-source components, each keeping its own licence — notably the Excalidraw whiteboard engine, under the MIT licence. The exhaustive list of components and their licences ships with the product and is regenerated with every release.
11 Troubleshooting
The most frequent symptoms and their real cause. The screen's diagnostics panel answers most of these questions without leaving the room.
| Symptom | Likely cause and fix |
|---|---|
| The screen shows “Kelra Room” instead of the room name | The screen is not provisioned, or its key has been revoked — the device was deleted from the console. Check the Devices tab; the screen shows its QR code again as soon as it is no longer recognised. |
| “Screen not recognised” | The device was deleted from the console. The “Re-provision this screen” button restarts the QR-code journey. |
| The screen asks for the server address at every start-up | The configuration is being written to a non-persistent location. Check the screen's configuration storage, or pin the address through an environment variable — which then takes precedence over the file. |
| The “Save” button on first launch stays greyed out | The connection test did not succeed. That is deliberate: a wrong address could no longer be changed from the screen. Check that the server answers from that machine and that the port is allowed through the firewall. |
| “Error: fetch failed” when creating an organisation | The message comes from the server, not the browser, and has nothing to do with the credentials entered: the server could not open the connection to the provider. Failing on Microsoft and Google at the same time confirms it — two tenants, two sets of secrets, one outbound path. Go back to the Network flow matrix: the four domains open on 443, the proxy declared in the environment: block, the corporate authority supplied to the server. From 1.0.5 on, this message is replaced by a sentence naming the cause and the action to take. |
| The schedule does not appear | Check that the organisation is connected — green status in the console — that the room's resource calendar address is correct, and that the permissions have actually been granted admin consent. |
| The “Join” button is missing or greyed out | The invitation carries no usable video link. On Google: edit the event and add a Meet conference. On Microsoft: the Teams link must be present in the invitation. |
| The times displayed are offset | The Windows machine's time zone or clock is wrong. The Clock line in the diagnostics compares the screen with the server and reports the drift. |
| A guest sees “socket down” on the whiteboard | The server address is not reachable from the guest's device — typically a VPN address, an internal container address, or localhost. Check that the server answers from a phone on the same network. |
| Guests cannot scan the whiteboard QR code | The kiosk port is not allowed through the screen's Windows firewall, or the detected address belongs to a virtual network adapter. The address can be forced through configuration. |
| The console is unreachable from one particular machine | Some browsers block requests to private IP addresses. Use Firefox, Edge or Chrome. |
| Cross-organisation conflicts are never declined | The resource calendar's native auto-accept is still on: the provider answers before arbitration happens. Turn it off on every calendar wired to the broker. |
| A “This site is trying to open Microsoft Teams” dialog appears | The protocol-blocking policy has not been applied on that machine (see Screen installation). |
| The screen is locked behind a licence message | The trial period is over, or the licence has expired. The console always stays reachable: that is where the unlocking key is entered. |
12 Licensing & pricing
One perpetual licence per screen, with no mandatory subscription. Hosted administration is an option, not a toll.
On-premise — €499 / screen
A perpetual licence, paid once. Every feature: room screen, calendars, real-time whiteboard, PDF minutes and email delivery. The server is hosted on your premises and no data leaves your network.
+ Hosted console — €8.99 / month / screen
The perpetual licence, plus a centralised admin console to drive the whole estate remotely: monitoring, configuration deployment, continuous updates and priority support.
Prices exclude VAT. Volume discount from 20 screens up.
How the licence works
| Rule | Detail |
|---|---|
| Trial | 30 days per deployment, with no key and no feature restriction. |
| Seats | One seat = one provisioned screen. Going over never cuts off a screen already in service: it only prevents enrolling a new one, and says so in the console. |
| Activation | Licence tab → paste the key → activate. The console then shows the customer, the seats used and available, and the expiry date if there is one. |
| Transfer | The licence can be released from the console in order to move a deployment to another server. It is tied to no hardware. |
| Perpetual licence | No expiry. The screen keeps working indefinitely, including with no connection to Kelra. |
| Fixed-term licence | Hosted-console offer only. On expiry the screens keep running for a further 10 days; the console reports the overdue renewal and refuses to enrol new screens. A warning appears as soon as fewer than 30 days remain. |
The kiosk shows nothing during the grace period: a customer should not learn about a late renewal from a meeting room going dark in front of their visitors. Raising the alarm is the console's job.
Software licence
Kelra Room is distributed under the Business Source License 1.1 — the same model as MariaDB, HashiCorp or Sentry:
- The source code is supplied, auditable and modifiable.
- Non-production use is free: development, testing, demonstration, evaluation.
- Production use requires a commercial licence, sold per screen, beyond a 30-day trial period per deployment.
- Every release automatically converts to the Apache License 2.0 four years after publication — a deployment is never stranded, whatever becomes of the vendor.
The licence text supplied with the product is the authoritative one; the summary above does not replace it. Third-party components keep their own licences.
13 Support
Before writing to us, three things speed the diagnosis up considerably.
- The screen's diagnostics panel — a photo is enough. It gives the IP address, the gateway, the server state, internet egress, the state of each calendar, the clock, and both versions (screen and server).
- The exact server version, readable in the console sidebar or at the
/healthendpoint — version, build fingerprint and date. - What changed recently: an update, a server address change, a permission change on the Microsoft or Google side, a network intervention.
Contact
hello@kelralabs.com — product questions, quotes, commercial licences.
Demonstration
Twenty minutes, on the screen of your choice — including your own. Request a demo.
Detailed documentation
The full installation guide, the third-party component list and the licence text ship with the product and are versioned alongside it.