Skip to content
Halo

Access policies

Policies that decide every sign-in.

Before Halo creates a session or sends someone back to an application, it asks the policy engine. That covers passkey and code sign-ins, magic links, federated sign-ins, silent sign-in with prompt=none and approving a halo login.

How Halo decides

Luna → AWS IAM Identity Center

Method
Passkey
Device
Trusted
Network
Office
Risk
None
  • Block high-risk sign-insEnforced
    No match
  • Require a passkey for administratorsEnforced
    Satisfied
  • Require a trusted device for productionReport-only
    No match
Allowed

Every matching policy is satisfied.

The engine

How Halo decides.

An allow policy never overrides a stricter policy that also matches. To exempt people, add them or one of their groups to the policy's exclusions.

  1. 01Blocked deviceIf an administrator blocked the device, the sign-in is refused.
  2. 02Method turned offIf the sign-in method is off for the organization, the sign-in is refused.
  3. 03Strictest enforced matchEvery enabled policy is checked. Of the enforced ones that match, block beats requiring a passkey, which beats allow.
  4. 04No matchWhen no enforced policy matches, Halo allows the sign-in.

Writing a policy

Who, where, on what, and how.

A policy matches only when every condition holds. Then it does one of three things.

  • AllowLet the sign-in through.
  • Require a passkey or security keyRefuse other methods. The person can sign in again with a phishing-resistant one.
  • BlockRefuse the sign-in. The sign-in log records the policy and its reason.
Policy conditions
ConditionMatches
PeopleEveryone, or chosen groups and people. Exclusions always win.
ApplicationsAll applications, or chosen ones. Halo itself covers the console and the account portal.
NetworkInside or outside chosen network zones, or any network.
DeviceTrusted devices only, or devices that aren't trusted.
RiskOne or more of none, low, medium and high.
Sign-in methodPasskey, security key, authenticator app, magic link, recovery code or identity provider.

Examples

Example policies
GoalApplies toCoversConditionEffect
Administrators always use passkeysGroup AdministratorsHalo—Require a passkey or security key
Block sign-ins from a risky networkEveryoneAll applicationsInside Tor exit nodesBlock
Keep high-risk sign-ins out of finance toolsEveryoneBillingRisk: highBlock
No magic links for production accessGroup ProductionAll applicationsMethod: magic linkBlock

Report-only

See the effect before you enforce it.

A report-only policy is evaluated on every sign-in like an enforced one, but never changes the outcome. The policy list shows, for the past 24 hours, how many sign-ins each policy matched and how many it would have stopped.

The simulator

Pick a person, an application, an IP address, a sign-in method and a device trust level. Halo shows the decision, the risk level with each signal, and why every enabled policy matched or didn't. A simulation records nothing.

The access policies page with report-only insights for the past 24 hours above the list of policies

Sign-in risk

Every sign-in gets a risk level.

The risk of a sign-in is the highest level among its signals, or none. The sign-in log shows it on every event, and policies can match on it.

Risk signals
SignalLevelWhen
Risky networkHighThe address is in a network zone marked risky.
Repeated failed sign-insHighThe account or the address typed had 5 or more failed sign-ins in 15 minutes.
New deviceMediumA browser this person has never used, when they already signed in from others.
New networkLowA /24 or /48 network this person has never signed in from before.

Risk events

Medium and high signals also open a risk event with the person, address, device and detail. A security administrator resolves it after acting, or dismisses it when it was expected.

The risk events page with a medium-risk new device event and a high-risk sign-in from a risky network

Context

Networks and devices policies can rely on.

Network zones

A zone is a named list of IPv4 and IPv6 addresses and ranges, up to 500 each, marked trusted or risky. Policies match on zones, and a risky zone raises every sign-in from it to high risk even when no policy names it.

Behind a reverse proxy, set HALO_TRUSTED_PROXIES so Halo sees the client's address.

Devices

Each browser gets a device cookie that identifies it to the policy engine but authenticates no one. Security administrators mark devices trusted or blocked. Blocking a device refuses its sign-ins and ends the sessions it started.

Infrastructure access

SSH certificates from the same identity.

Halo runs an SSH certificate authority. Security administrators map groups to unix account names, and halo ssh-cert signs a person's public key for every principal their groups map to.

Certificates last 8 hours by default, adjustable from 5 minutes to 24 hours. sshd cannot ask Halo whether a certificate is still wanted, so the lifetime is the main control.

Trust Halo on a server
$ curl -fsS https://auth.example.com/api/v1/ssh/ca.pub | sudo tee /etc/ssh/halo_user_ca.pub$ echo "TrustedUserCAKeys /etc/ssh/halo_user_ca.pub" | sudo tee -a /etc/ssh/sshd_config$ sudo sshd -t && sudo systemctl reload sshd
Infrastructure access guide
luna@laptop
$ halo login --server https://auth.example.comOpen https://auth.example.com/device?user_code=WDJB-MJHTand check that the page shows the code WDJB-MJHT.Waiting for you to approve the sign-in…Signed in to https://auth.example.com as Luna <luna@example.com>.$ halo ssh-certWrote certificate 1042 to /home/luna/.ssh/id_ed25519-cert.pub.Log in as ops, deploy until 5 October 17:41 CEST.$ ssh ops@db-1.internal
The infrastructure access page, showing the certificate authority's public key, its fingerprint and the certificate lifetime

Run Halo on your own infrastructure.

One command on a Linux host with Docker. Then create your administrator and register a passkey.

curl -fsSL https://halo.scala.gg/install.sh | sh