home-assistant/core · error · Unauthorized

Unauthorized

Error message

Unauthorized

What it means

Unauthorized is Home Assistant's permission-denied error. Here it is raised when the calling user exists but their permission policy does not grant POLICY_CONTROL over the target assist_satellite entity (perm_category CAT_ENTITIES). It is the standard enforcement point for entity-scoped control permissions in a service handler.

Source

Thrown at homeassistant/components/assist_satellite/__init__.py:119

            cv.has_at_least_one_key("start_message", "start_media_id"),
        ),
        "async_internal_start_conversation",
        [AssistSatelliteEntityFeature.START_CONVERSATION],
    )

    async def handle_ask_question(call: ServiceCall) -> dict[str, Any]:
        """Handle a Show View service call."""
        satellite_entity_id: str = call.data[ATTR_ENTITY_ID]
        if call.context.user_id:
            user = await hass.auth.async_get_user(call.context.user_id)
            if user is None:
                raise UnknownUser(
                    context=call.context,
                    permission=POLICY_CONTROL,
                    user_id=call.context.user_id,
                )
            if not user.permissions.check_entity(satellite_entity_id, POLICY_CONTROL):
                raise Unauthorized(
                    context=call.context,
                    permission=POLICY_CONTROL,
                    user_id=call.context.user_id,
                    perm_category=CAT_ENTITIES,
                )

        satellite_entity: AssistSatelliteEntity | None = component.get_entity(
            satellite_entity_id
        )
        if satellite_entity is None:
            raise HomeAssistantError(
                f"Invalid Assist satellite entity id: {satellite_entity_id}"
            )

        ask_question_args = {
            "question": call.data.get("question"),
            "question_media_id": call.data.get("question_media_id"),
            "preannounce": call.data.get("preannounce", True),

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. Grant the calling user control permission for that entity (User settings > Permissions, or admin policy)
  2. Run the service as a user with the control permission over assist_satellite entities
  3. Verify the entity_id in the service call matches an entity the user is allowed to control
  4. If using a users.yaml policy, add the entity under entity_perms > control and reload permissions
Defensive patterns

Strategy: validation

Validate before calling

if (
    (user := await hass.auth.async_get_user(call.context.user_id))
    and not user.permissions.check_entity(satellite_entity_id, POLICY_CONTROL)
):
    _LOGGER.warning("User %s lacks control on %s", user.id, satellite_entity_id)

Try / catch

try:
    await hass.services.async_call("assist_satellite", "ask_question", {...})
except Unauthorized:
    # surface a permission message to the caller / pick an entity the user may control
    raise

Prevention

When it happens

Trigger: A non-admin user without control rights over the satellite entity calls assist_satellite.ask_question on it; a restricted user whose entity_perms policy excludes the entity's entity_id; entity_id belongs to a different area/user scope than the caller may control.

Common situations: Users created with limited permissions attempting voice-satellite actions; newly added satellite entity not included in the user's allowed entities; YAML admin/user permission files that were edited but not reloaded.

Understand the failure class

Related errors


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/f34edddb377b4864. Report an issue: GitHub.