Check sign-in patterns and origins
You want to know when sign-ins reach the service, where they come from, and whether they show signs of an attack—say, a burst of wrong keys from another country, or one key used on several continents within a day.
Solution overview
The service keeps a sign-in log in the log file next to the administration store: every sign-in decision with its method, outcome, refusal reason, person, and origin. It classifies the origin without any outbound connection—through a geolocation database stored on the server and through the networks you name yourself. Every minute it applies sign-in rules to the new events and stores what they detect as a finding—over months, measured against what is usual for each person. You evaluate it through the administration API:
| Set or command | Shows | Right |
|---|---|---|
SignInHours | counts per hour, method, outcome, country, and network class—without person or address | admin |
SignInOrigins | origins per named network, subnet, country, and network operator | admin |
SignInFindings | the stored findings with rule, level, text, and suggestion | admin; person, key, and comparison values only with sign-in-events |
sign-in-profile | what is usual for one person over 90, 180, 365, or more days | sign-in-events |
SignInEvents | the individual events with address and person | sign-in-events |
SignInAdvice | notable patterns of the last seven days, computed when read | admin; person only with sign-in-events |
Time as the server sees it. Hour and weekday follow the server's clock. A sign-in from Tokyo and one from Berlin at the same instant land in the same hour. That is exactly what tells you when the service is under load and when an attack is running, whatever the caller's local time.
Implementation
Provide the geolocation database. Without it, the log only tells whether an address belongs to one of your networks, a private network, or the public internet—no country, no network operator. Pick the path that fits your server:
Situation Path The server reaches the internet Choose a source and let the service download it: POST /admin/v1/set-geoip-sourcewith{ "source": "dbip-lite", "updateDays": 30 }, thenPOST /admin/v1/update-geoip. WithupdateDays, it refreshes on its own from then on.Only the administrator's workstation reaches the internet The administration app downloads the files and hands them over with POST /admin/v1/upload-geoip.Neither server nor workstation reaches the internet Get the files another way and hand them over with upload-geoip, or import them on the server with the `import-geoip` command.You can choose DB-IP Lite (no account, CC BY 4.0 license) or MaxMind GeoLite2 (with the account ID and license key of your MaxMind account); see Geolocation database sources. Both licenses require attribution. The service returns the text in
GeoIpFiles.Attribution; anything that displays origins displays it too.Name your own networks. Add the networks of your sites to the configuration so the log shows “Plant 3” instead of a private address:
"Gateway": { "SignInLog": { "Networks": [ { "Name": "Headquarters", "Network": "10.1.0.0/16" }, { "Name": "Plant 3", "Network": "10.3.0.0/16" } ] } }Grant the individual events only to those responsible. Any rule with
adminreads the sets with counts and patterns. The address and person behind each sign-in are personal data; only a rule that literally names thesign-in-eventsresource as well reads them:{ "Id": "security", "Resources": [ "admin", "sign-in-events" ], "Verbs": [ "GET" ], "ReadOnly": true }In the administration store, that's a
resource=sign-in-eventsentry underClientRuleItems.Have findings reported. So that an attack reaches someone even at night, add recipients and set up mail delivery:
"Gateway": { "SignInLog": { "TimeZone": "Europe/Berlin", "Alerts": { "Recipients": [ "security@example.com" ], "DigestHour": 7 } } }Findings at level
act(attack patterns, a key that was passed on) go out by mail right away; findings at levelask(something is new for a person) go out once a day as a digest. Without recipients, findings appear only in the service log and inSignInFindings.Read the findings.
SignInFindingslists each finding with rule, level, time, text, and suggestion; the rules and their thresholds are in the reference. A program remembers the highestIdit has read and from then on asks only for what is new:GET /admin/v1/odata/SignInFindings?$filter=Id gt 4711
Observedis the value seen,Usualwhat is usual for the person;EventIdsleads to the individual events inSignInEventswhile they're still in the log file.Look up a person's profile. To put a finding in context—“is Italy new for Frank, or just rare?”—request the sign-in profile for the period you're interested in:
POST /admin/v1/sign-in-profile Content-Type: application/json { "person": "Frank Mustermann", "days": 365 }The findings themselves always compare with the 90 days before the event; the profile's period changes only the view.
- Analyze the distribution. For a weekly view, group
SignInHoursbyWeekday(1 = Monday) andHourOfDay; for a map, useLatitude/LongitudefromSignInOrigins.Originnames the address or network in the form a sign-in rule accepts underfrom.
Remarks
- What is counted. A successful sign-in appears once per 15 minutes, person, method, and origin—not on every request. Equal refusals within one minute are stored as one event with a count (
Repeats). A request without credentials that the service answers with its sign-in methods isn't a failed attempt: every Windows sign-in starts that way. It appears aschallengeand isn't counted under “denied” in the service status. - Not counted are requests from a signed-in caller who merely lacks the right for an object, and requests to a database that can't be read—they say nothing about the sign-in.
- Origin behind a proxy. The origin is the address that reaches the service; behind a trusted proxy, it's the forwarded one. If the proxy isn't registered, every sign-in shows the proxy's address.
- Retention. Individual events, profiles, and findings stay until the log file reaches its size (
Gateway:Store:LogMaxMegabytes, default 4,096 MB); then the oldest go first, findings last. Hourly counts stay for 400 days (Gateway:SignInLog:HourDays). Coordinates are rounded to one decimal place (about 10 km); a geolocation database is approximate anyway and usually places an address in the network operator's city. - Co-determination. In Germany, an evaluation that compares the sign-in behavior of individual employees over a longer period can be subject to co-determination by the works council (a technical facility for monitoring). Clarify its use with those responsible in your organization beforehand. This is a note, not legal advice. The service doesn't rank persons, keeps times in profiles only on an hourly grid, and shows a profile only on an explicit request for one person.
- Keys never appear in the log, only their ID. An unknown SQL Server login name is recorded so that attempts with many names become visible.
Related topics
- Configuration: Gateway:SignInLog—all settings
- Administration API: sign-in log and geolocation database—fields and commands
- Tier access by location—rules by origin