# Account & security

A Lessly account is one person's identity on the platform. It is created once, identified by an email address, and reused everywhere: the web application, the API, and any application you authorize to act on your behalf. An account is always a human identity — machine access uses separate credentials and is not tied to a personal account beyond the account that created it — see [issue an API key](/interfaces/api-and-keys).

This page covers how you get in and how that access behaves over time: signing in, the second factor, what you grant to applications, and the sessions a sign-in creates.

## Sign in

Two sign-in methods exist today, and two surfaces carry them.

| Where | How you sign in | What you get |
|-------|-----------------|--------------|
| `app.lessly.com` | Email and password, or Continue with Google / Continue with GitHub | Authentication state as browser cookies, and a session |
| `lessly` CLI | `lessly auth login` (device flow), or `lessly auth login --token` for an agent or CI job | A token the CLI sends on every call |

### With an email and password

1. Register with an email address, a password, and a display name.
2. Sign in with that email and password. Lessly never stores your password itself — credential storage and password checking are delegated to an external identity provider, and only the account record lives on the platform.
3. If your account has a second factor, Lessly asks for it before you are signed in.

When sign-in completes, the browser receives its authentication state as cookies. The application never reads the tokens from JavaScript.

### With Google or GitHub

The sign-in page also offers **Continue with Google** and **Continue with GitHub**. Choosing one sends you to that provider, where you log in and approve the request; the provider sends you back to Lessly, which then signs you in.

- **Signing in and signing up are the same action.** If no Lessly account matches the provider profile, one is created from it on the spot, from the verified provider profile. There is no separate "register with Google" form.
- **Linking to an existing account requires a verified email.** If the provider reports an email that already belongs to a Lessly account, the two are linked only when the provider asserts that the address is verified. Otherwise they are not linked, and ownership has to be proven first.

Social sign-in is offered on the main sign-in page. The consent screen shown to third-party applications stays on email and password.

> **ARRIVING THROUGH AN INVITATION**
> The invitation is carried through the provider round trip, so an invited person is never asked for anything extra. An invitation that cannot be used lands on an explicit "this invite can't be used" screen rather than failing silently.

### From the CLI

A person at a terminal runs:

```bash
lessly auth login
```

This starts a device authorization flow: the CLI prints a short user code and a verification URL, you approve the request in a browser, and the CLI picks up the resulting token.

An agent or a CI job passes a product-scoped token instead, which needs no browser and no interaction:

```bash
lessly auth login --token "$LESSLY_TOKEN"
```

See [drive Lessly from the terminal](/interfaces/cli).

### Confirm which identity you are signed in as

[`organization_auth_me`](/reference/mcp-tools/organization_auth_me) returns the current identity — `email`, `identityId`, `displayName` — and takes no arguments. Over REST it is `GET /governance/api/v1/auth/me` — [read the Organization API](/reference/openapi/organization).

Signing in and signing out themselves are UI-only: the Lessly MCP catalog carries no tool for either step, because sign-in hands the browser its authentication state as cookies. What an agent or MCP client does instead is ask you for access to your account — see [Let an application act on your behalf](#let-an-application-act-on-your-behalf).

## Turn on two-factor authentication

Two-factor authentication (2FA) adds a second step to sign-in: after your password or social sign-in is accepted, you also prove you hold a second factor. Two factors exist, and they work together:

- **An authenticator app (TOTP).** A standard time-based one-time code — six digits, changing every 30 seconds. Any standard authenticator app works.
- **Recovery codes.** Ten single-use codes generated when you turn 2FA on, for when you cannot reach your authenticator app. A recovery code is accepted anywhere a TOTP code is.

There is no SMS factor and no security-key factor. Lessly owns the second factor itself: your password still lives with the external credential provider, but the authenticator secret and recovery codes belong to your Lessly account.

From Account → Security in `app.lessly.com`:

1. **Start enrollment.** Lessly generates a secret and shows it as a QR code and as text. Scan or type it into your authenticator app. At this point 2FA is not active yet — the secret is only provisional.
2. **Confirm with a code.** Enter the six-digit code your app now shows. This proves the app is set up correctly and activates the factor.
3. **Save your recovery codes.** Ten codes are shown once, immediately after activation. Lessly keeps only their hashes and cannot show them to you again. Store them somewhere safe.

Enrolling, regenerating recovery codes, turning 2FA off, and managing trusted devices are UI-only: the Lessly MCP catalog carries no tool for any of them, and each is done under Account → Security.

### Sign in with 2FA on

Sign in as usual. Once the first step is accepted, you are not signed in yet: nothing is issued until the second step succeeds.

- **In the web application,** you are taken to a code page. Enter the code from your authenticator app, or one of your recovery codes.
- **When authorizing an application,** the same code step appears inside the authorization flow, and the flow resumes where it left off once you pass.

> **THE CODE STEP IS LIMITED**
> You have a limited number of attempts per sign-in. A wrong code tells you how many attempts remain; running out — or waiting too long, the step expires after five minutes — cancels it and you start the sign-in over. A code is accepted only once, so a code that has just been used will not work a second time.

### Trust a device

At the code step you can choose to remember the device. Lessly then skips the second step on that device for 30 days. Trust is tied to that one browser on that one machine — every other device still asks.

Trusted devices are listed under Account → Security and can be removed individually. All of them are dropped when you turn 2FA off, change your password, or sign out everywhere. If your organization's policy forbids trusted devices, existing ones stop being honoured immediately.

> **A TRUSTED DEVICE IS NOT A SESSION**
> A trusted device has its own 30-day life and its own list under Account → Security. Ending a session does not untrust the device.

### Manage or remove 2FA

Under Account → Security you can:

- See whether 2FA is on, which factors are active, how many trusted devices you have, and how many recovery codes are left.
- **Regenerate recovery codes.** A fresh set of ten replaces the old ones, shown once.
- **Turn 2FA off.** This also removes all trusted devices.

Regenerating recovery codes, turning 2FA off, and managing trusted devices are sensitive actions. Each requires you to confirm it is really you by re-entering your password or a current authenticator code shortly beforehand — signing in earlier in the day is not enough. Accounts that sign in with Google or GitHub and have no password use the authenticator code for this.

### When your organization requires 2FA

An organization can require 2FA of its members — [see how the policy is set](/access/organizations-and-members). While it applies to you:

- **You cannot turn 2FA off.** The attempt is refused as long as the policy applies to you.
- **If you have not enrolled yet, you are made to enrol at sign-in.** The enrollment runs inside the sign-in itself, and you are signed in once it finishes. If you are already signed in when the policy starts applying to you, it takes effect the next time you sign in.
- **The policy can also switch off trusted devices,** so every sign-in asks for a code.

## Let an application act on your behalf

Applications — including agent and MCP clients — never receive your password. The **OAuth 2.1 authorization code flow with PKCE** is the only way to get access to your account programmatically; PKCE is mandatory, and there is no implicit flow. What you do, in order:

1. **The application sends you to Lessly.** It opens the Lessly authorization page with the access it wants (its scopes) and a proof value it will have to repeat later.
2. **You sign in.** Lessly shows its own sign-in page — the application never sees your credentials. If your account requires a second factor, you provide it here.
3. **You approve the access.** Lessly lists the scopes being requested and you grant or deny them. Denying returns you to the application with an "access denied" answer and nothing is issued.
4. **Lessly sends you back.** The browser returns to the application with a one-time authorization code.
5. **The application exchanges the code** for its own credentials, proving it is the same application that started the flow.

The scopes you can be asked for are:

| Scope | What it gives the application |
|-------|------------------------------|
| `openid` | Confirmation of who you are. Required. |
| `profile` | Your display name and avatar. |
| `email` | Your email address. |

After you approve:

- **Approval is remembered per application.** The next time the same application asks for the same scopes, you are not prompted again. Asking for a scope you have not granted before does prompt you, and the new scope is added to what you already granted.
- **Access is time-limited.** The access an application holds expires after an hour and is renewed in the background without involving you. The renewal credential itself expires after 30 days of not being used.
- **Renewal detects theft.** Each renewal replaces the previous credential. If an old one is presented again after it was replaced, Lessly treats it as a stolen credential and revokes the whole chain, which signs that application out.
- **The authorization code is single-use** and expires ten minutes after it is issued. Using one twice revokes everything issued from it.

An application can hand back its access at any time, which also invalidates everything derived from it. Doing so does not sign you out of Lessly itself — your own sessions are separate from what you granted to applications.

## Sign out and end a session

A session is one sign-in on one device. Every time you sign in, Lessly creates a session and records the device it belongs to; from then on that device is signed in until the session ends.

**Sign out.** Signing out ends the session you are currently using: the session is revoked, the credentials tied to it stop working, and the browser's authentication cookies are cleared. Other devices keep their own sessions.

Sessions also end without you doing anything when:

- either expiry limit below is reached;
- the ten-session limit pushes out your oldest session;
- your account is suspended or deleted, which stops every authentication path immediately.

Revoking a session does not erase its record — the record is kept for auditing.

A session is not the access an application holds, and it is not an API key. Ending a session does not withdraw an application's access, an application renewing its access does not extend or create a session, and neither one touches the API keys issued for machine access. Revoking any of the three leaves the other two working.

### How long a session lives

Two limits run at the same time, and whichever is reached first ends the session.

- **30 days of inactivity.** The clock restarts every time the session is used, so a session you keep using does not expire on this limit.
- **90 days in total.** This one never restarts. Ninety days after you signed in, the session ends regardless of how active it was, and you sign in again.

Within a live session, the short-lived credential your browser holds is renewed in the background roughly every hour. You do not see this, and it is not the same thing as the session expiring.

### How many sessions you can have

Ten at a time. Signing in on an eleventh device does not fail — Lessly ends your oldest session to make room. In practice this means signing in on many devices gradually signs out the ones you stopped using.

### What a session records

| Recorded | Why |
|----------|-----|
| Device fingerprint | Identifies the device the session belongs to. |
| Device name | The readable name you see, such as "Chrome on macOS". |
| IP address | The address the sign-in came from. |
| Creation and last-activity time | Drive the two expiry limits above. |

## Next steps

- [Sign in from the terminal](/interfaces/cli): the commands the CLI takes and the exit codes it returns.
- [Issue an API key](/interfaces/api-and-keys): machine access that outlives any session of yours.
- [Set up your team](/get-started/set-up-your-team): invite people into the organization your account belongs to.
- [Look up what the account holds](#reference-what-the-account-holds): the field and status tables, and the fields no one can change after the account is created.
- [Read the identity call](/reference/openapi/organization): `GET /governance/api/v1/auth/me` and the rest of the Organization API.

## Reference: what the account holds

| Field | What it is |
|-------|-----------|
| Email | The unique identifier of the account. Two accounts cannot share an email. |
| Email verified | Whether the address has been confirmed by clicking the verification link. |
| Display name | The name other members of your organization see. |
| Avatar URL | Optional picture shown next to your name. |
| Locale, timezone | Presentation preferences stored with the account. |
| Status | `ACTIVE`, `SUSPENDED`, or `DELETED`. Only an active account can sign in or call the API. |

Other people in your organization can read only the public part of a profile: the identifier, display name, avatar, and status. Your email address is not part of that public profile. Your password is never stored by Lessly in a readable form, and accounts that sign in with Google or GitHub have no Lessly password at all.

You get an account in one of three ways:

- Registering with an email address, a password, and a display name.
- Signing in with Google or GitHub for the first time, which creates the account from the verified provider profile.
- Accepting an invitation to an organization or a product, which walks you through one of the two above.

Registration sends a verification email; clicking the link marks the address as verified.

An account is not itself a container for work. Products live inside an organization, and an account reaches them through organization membership; your organization role and the products you can reach are set by an owner or admin of that organization, not by you — [see how organizations and products fit together](/concepts/platform-model).

### What you can change, and what you cannot

You can change:

- **Two-factor authentication.** Enrol, disable, regenerate recovery codes, and manage trusted devices under Account → Security.
- **Email verification.** Confirm your address from the link Lessly emails you.
- **Active organization.** Switch between the organizations you belong to.
- **Sign-in state.** End your current session by signing out.

Several fields have no self-service way to change them. Display name, avatar, locale, and timezone are set when the account is created — from what you typed at registration, or from the profile the provider returned on your first social sign-in — and there is no page or API call that edits them afterwards. The same is true of the email address itself and of the password: neither can be changed from the account, and there is no self-service password reset.

### Suspended and deleted accounts

Status is checked on every authentication path — password sign-in, token sign-in, token refresh, and each authenticated request. A suspended or deleted account is rejected at all of them, so revoking access takes effect immediately rather than at the next token expiry. A deleted account is also hidden from profile lookups.
