Sign in
Fleet has no password form of its own. Sign-in happens at Wazuh ID (id.wazuh.com), the single account for the whole Wazuh ecosystem, and the console at fleet.wazuh.com receives the resulting session. An account created for another Wazuh product is the same account here, and creating one is done on Wazuh ID rather than in Fleet.
Signing in needs a Wazuh ID account and nothing else. There is no access list to be added to and no approval to wait for: the first request after you sign in sets your workspace up, and the console opens. For what Fleet does once you are in, see What is Fleet.
The sign-in flow
Opening any console route while signed out routes to /login. The screen shows
one control, Sign in with Wazuh ID, which starts an OAuth authorization code
flow with PKCE against Fleet's hosted sign-in domain, with
identity_provider=WazuhID and the scopes openid email profile. Wazuh ID asks
for credentials and the browser returns to /auth/callback on the Fleet origin,
where the code is exchanged for tokens and the console loads.
The console holds the ID token rather than the access token, since that is the
one carrying email and the tenant claim. Calls to api.fleet.wazuh.com carry
it as a bearer, attached in one place rather than at every call site, and the
API verifies the signature against the pool's published keys. No Wazuh
credential is ever in the browser: see
Data handling.
The silent probe, and why sign-in is usually invisible
Before the button is shown at all, the login screen checks for a session you already have.
- If this browser already holds a Fleet session, the login page replaces itself with the console. No hosted UI, no trip to Wazuh ID.
- Otherwise a hidden same-origin iframe runs the same flow with
prompt=none. If your shared Wazuh ID session is live the chain resolves in redirects, the framed/auth/callbackexchanges the code, and the console opens with no click. - With no shared session the button is revealed instead, and quickly: the Wazuh ID login form rendering inside that hidden frame is a cross-origin document, which is the signal to show the button at once. A 5 second backstop covers a hung network.
The probe runs at most one automatic attempt per visit: a reload within 30 seconds does not re-run it, and a later one may. It never runs while a sign-out is in flight, and never in a background tab, where two tabs mid-flow would clobber each other's state. Clicking the button always starts the flow whatever the probe did. Every failure path reveals the button, so the worst case is the ordinary sign-in card.
A sign-in failure is shown on /auth/callback with a Back to sign in link.
The one case handled for you is Wazuh ID linking a new identity to an existing
account: that first attempt fails with an ACCOUNT_LINKED_RETRY marker, and
Fleet retries once.
How your workspace is set up
Fleet holds your hosts in a workspace, and a workspace is one
organization. The console does not ask you to create one. With a session in hand
it asks GET /api/activate whether this identity already has a workspace, and
POSTs to the same route if it does not. There is no button whose only purpose is
to be clicked once: signing in is the consent, and following an invitation needs
no extra step either.
That POST resolves the account to exactly one workspace, and the order of the answers is what keeps it to one:
- an account that is already set up, or that already holds a membership, keeps the workspace it has and is never moved to another;
- an account that already has hosts of its own, or a Wazuh Cloud account paired to Fleet, keeps them and administers that workspace;
- a pending invitation joins the inviting organization, with the role and the host access the invitation carries;
- otherwise Fleet asks Wazuh Hub which organization the account belongs to. If that organization already uses Fleet, the account joins the existing workspace as a member. If it does not, the workspace is created and the account administers it.
The first person from an organization to open Fleet administers its workspace. Everyone who arrives afterwards joins as a member, and an administrator changes that from the Team page. No role is read from Wazuh Hub: being an owner there is not being an administrator here.
One organization is one workspace, and the last answer above is where that could break. When Wazuh Hub names the organization but not the workspace it uses, Fleet falls back to its own record of which organization uses which workspace, so a teammate joins the one their colleagues already have rather than starting a second one beside it.
Activation also records which Wazuh Hub organization the workspace belongs to.
That is the record the fallback above reads, and the one the other Wazuh
products read to find your workspace at all, so a workspace whose organization
was never recorded is invisible to them until somebody from it signs in again.
The route sits outside the access gate on purpose,
because it is the door: somebody it cannot set up needs to be told why rather
than given a 404.
Membership is re-read on every request
Once the workspace exists, being allowed to use the API is one thing only: membership of it, meaning an account that has been set up and is listed as a member of your organization's workspace. Nothing else admits anybody.
The tenant claim stays stamped on a Wazuh ID user until something blanks it, so a token proves that somebody was admitted once, not that they still are. The API therefore reads their membership from the database on every request rather than trusting the token. Removing a person from the Team page takes effect on their next request, and the same rule decides which hosts a member may open, re-checked by the control plane on every request for one.
To a caller who is not admitted, the console-facing API routes answer 404 Not found, the same body an unknown host gets: a stranger must not be able
to tell "this workspace has no such host" from "this feature is not for
you". The activation route is the exception, and deliberately: it is the door,
so it answers with a reason rather than a 404.
When a workspace cannot be set up
Nobody is refused for who they are, but the setup can still fail to resolve, and it says so rather than opening an empty console. You are signed in, and the console is replaced by a full-screen panel: a title, a short explanation, Signed in as with your address, and two controls, Go to Wazuh Hub and Sign out.
These are the outcomes worth naming.
| What the panel says | Reason | What it means, and what to do |
|---|---|---|
| You are not on this organization's Fleet list | not_granted | Your session still names a workspace you are not a member of, which is what being removed from the Team page leaves behind. An administrator can invite you again from Team |
| You already have your own Fleet workspace | workspace_conflict | You already have hosts of your own, and the workspace resolved for you is a different one: an invitation into somebody else's, or an organization that was already using Fleet. Fleet will not move you and leave your hosts behind. Contact support |
| We could not confirm your access | hub_unreachable | Wazuh Hub did not answer, so which organization you belong to could not be established. Nothing was set up and nothing was refused. Try again in a few minutes |
| We could not confirm your access | anything else | The check failed for some other reason. Nothing was set up. Try again, and contact support if it keeps happening |
The last two rows matter more than they look. A failed check is never rendered as one of the refusals above: telling somebody they have no access when a request merely failed is a failure dressed up as a fact. And while the check is still in flight the console paints nothing at all, neither the product nor a wall.
Signing out
Sign out from the profile menu at the top right of Fleet's account screens, such as Overview, Hosts and Team. The full-screen panel above carries the same control.
Fleet's own sign-out is only half of one. Revoking Fleet's tokens leaves the
shared id.wazuh.com session alive, and the next "Sign in with Wazuh ID" would
restore the same account without ever asking for a password. So signing out is a
chain of four hops across two origins:
| Hop | What happens |
|---|---|
| 1 | Fleet asks for a global sign-out, revoking this account's Fleet refresh tokens on every device, then the hosted UI's /logout runs. If that call fails, on an already expired or revoked token, the sign-out still completes locally and the chain continues |
| 2 | The browser lands on /auth/logged-out on the Fleet origin |
| 3 | That page forwards to id.wazuh.com/logout, which ends the shared Wazuh ID session |
| 4 | Wazuh ID returns the browser to the Fleet root, and Fleet forwards it to the Wazuh Hub |
Hop 4 returns through Fleet rather than going straight to the Hub because Wazuh ID matches a logout destination exactly against the addresses registered for Fleet, and the Hub's is not one. An unregistered destination is not honoured at all, leaving the shared session alive.
Because every hop is a new document, the intent to sign out is recorded in both
sessionStorage and localStorage, with a 90 second deadline that is stamped
again on the way through hop 2, so a slow hosted UI cannot expire it mid-chain.
If id.wazuh.com is unreachable, blocked by a proxy or slow, the page stops
waiting after 8 seconds and says so: Fleet has signed you out on this device,
the last step has not answered, and signing in again may not ask for your
password. It offers Try again and a link to the Wazuh Hub. A successful hop
replaces the document long before that timer, so the panel only appears when
something is wrong.
With sessionStorage and localStorage both blocked the chain still runs and
both sessions are still correctly ended. Only the destination degrades: the
landing on the Fleet root cannot tell a sign-out from an ordinary visit, so it
shows Fleet's login page instead of the Hub. That was chosen over the opposite
failure, which bounces such a browser off Fleet on every visit.
Nothing pushes a token revocation to a tab already loaded, so the console re-reads the session whenever a tab returns to the front, and a sign-out performed elsewhere is noticed there.
The playground needs no account
playground.fleet.wazuh.com is the same console built with no sign-in pool and no backend, on invented data. It signs nobody in and reaches no Wazuh deployment. See The playground, and Add your first host once you are in.