Repository navigation
Security
Maquette runs in your Home Assistant frontend with the rights of the logged-in user. Import plans and templates only from people you trust; the card still protects you as follows.
- Sensitive actions are always confirmed
- Force the confirmation:
confirm: true - Import check
- What a plan can never do
- Report a vulnerability
Every service called from the plan (room buttons, widgets in side panels and cards, on / off switches, Activate buttons) is checked against a list of safe services. Any other service opens a dialog that names:
- the real action and the service (
lock.unlock), whatever the button's label says; - the target entities (name and id);
- the keys of the data sent, never their values (a code stays hidden).
The title is the action: Unlock?, Open the door?, Turn on?, Turn off?, Toggle?, Change the set point?, Run the script?… Cancel has the focus; Escape cancels.

| Safe (no dialog) | Sensitive (always confirmed) |
|---|---|
turn_on, turn_off, toggle of lights, switches, fans, input booleans, humidifiers, media players, climates, remotes, automations; settings of fans, humidifiers, climates, water heaters and media players |
lock.unlock, lock.open
|
scene.turn_on; values of input_number, number, input_select, select
|
alarm_control_panel.alarm_disarm, alarm_trigger
|
cover.close_cover, stop_cover; valve.close_valve, stop_valve
|
Opening a cover, unless every target is a shutter, blind, curtain, awning or window (device_class): garage doors, gates, doors and covers without a class are confirmed |
lock.lock; alarm_control_panel.alarm_arm_*
|
valve.open_valve, set_valve_position, toggle
|
homeassistant.turn_on / turn_off / toggle when every target is in a safe domain |
script.*, button.press, input_button.press, automation.trigger, homeassistant.restart / stop, shell_command, rest_command, notify… and any service not listed as safe
|
The exact list is in Reference › Security.
confirm: true asks for confirmation even for a safe service, on anything that calls one:
| Where | What is confirmed |
|---|---|
Room buttons (rooms[].actions[].confirm) |
The button's service |
Badges, openings, connected furniture (confirm on the element) |
Their on / off switch, in their card and in the room view |
Widgets (confirm on the widget) |
Switches and Activate buttons of its rows, thermostat −/+, cover and lock buttons |
Typical case: a garage door, a gate or a heater driven by a switch.
| The option on a badge | The dialog for a safe service |
|---|---|
![]() |
![]() |
badges:
- entity: switch.garage_door
pos: [120, 40]
confirm: true # on and off are confirmed, from the card and from the room view
rooms:
- name: Living room
poly: [[0, 0], [450, 0], [450, 380], [0, 380]]
actions:
- {name: All off, icon: mdi:power, action: homeassistant.turn_off, target: room, confirm: true}-
confirm: falsenever removes the confirmation of a sensitive service. -
coverwidgets confirm by default for garage doors, gates, doors and valves;lockwidgets always confirm Unlock and Open. -
protected: true(badges, openings, furniture) keeps the device from being turned off from the plan: no "off" switch in its card, switch greyed out while on in the room view.
In the editor: Always ask for confirmation on a room button, in the card section of a badge, opening or piece of furniture, and on list and thermostat widgets; Confirm before acting on cover and lock widgets.
Export / import › Import (a file, a paste or a template) first shows a summary and applies nothing until you click Import:
- the services of the room buttons, sensitive ones marked Confirmed on every tap;
- the entities controlled by widgets (cover, lock, thermostat, Activate rows);
- the More info links;
- the values removed as invalid, with their path (
rooms[0].poly,badges[8].color…); - the dashboard keys of the file that are ignored (
view_layout,grid_options,visibility,card_mod…): the card keeps its own.

Re-importing the plan unchanged applies it directly. Limits: 2 MB of text, 40 levels of nesting, 5,000 items per list; YAML is read without its extended types. Drafts and copies kept in the browser are read back the same way.
-
Run code. Every value is checked before it is drawn: coordinates and numbers must be finite numbers, enumerated
values must be known, texts are always shown as text. An invalid value is removed, with one warning in the browser
console (
maquette-card : invalid value(s) removed: …). -
Use a strange colour. Colours accept
#rgbto#rrggbbaa,rgb()/hsl()with numbers, a CSS colour name (red,teal…) or a theme variable (var(--primary-color)). Anything else is removed, so a colour can never load an image or restyle the page. -
Load something from another site. The card makes no request outside Home Assistant. People's avatars are shown
only when their picture is served by Home Assistant itself (a path starting with
/); otherwise their initials. - Act on its own. Nothing is called without a tap; history, statistics and related items are only read.
Where the plan and its copies are stored: Privacy, security and performance.
Please do not open a public issue: use Security › Report a vulnerability on the
repository. See SECURITY.md in the repository.

