| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| Nelsar.Axia 0.2.0 source code.tar.gz | 2026-10-13 | 2.0 MB | |
| Nelsar.Axia 0.2.0 source code.zip | 2026-10-13 | 2.4 MB | |
| README.md | 2026-10-13 | 5.3 kB | |
| Totals: 3 Items | 4.4 MB | 1 | |
Hardening after the first release, and fixes to the console. Upgrading from 0.1.0 takes one step: the API's container no longer runs as root, so its volumes have to be handed to uid 1654 before the new image starts — see Changed.
Security
- An account switched off in the directory loses its session within 30 seconds, instead of keeping it until the token expires: disabled or expired in Active Directory, locked by an administrator through OpenLDAP's password policy, or login-disabled in eDirectory. It can no longer sign in either, including against a directory that does not enforce those flags itself. A lockout after failed sign-ins does not count, so that nobody can end someone else's session by mistyping their password.
- Directory calls give up instead of waiting indefinitely: a directory that accepts the connection and then does not answer is reported as unavailable after
Ldap:OperationTimeoutSeconds, so it can no longer tie up the API's request threads. This includes StartTLS, which the LDAP library could not time out on its own. - Bulk batches are bounded: 100 rows when processed while the caller waits, 10,000 when queued, and at most 10 jobs waiting in the queue — a full queue answers
503withRetry-After. A queued job's status and results can only be read by the account that queued it, in the same directory; before, anyone holdingusers.bulkcould read any job by its id. - Organizational units and computers are held to the same rule as accounts and groups: nobody acts on something more powerful than they are. Renaming or moving a unit is judged by what it holds — a group mapped to a role the caller lacks, anything privileged in the directory, or the bind account — because everything beneath it is re-addressed; with
orgunits.manageandusers.update, moving the unit that held the Admin group used to be a way to reset an administrator's password. Domain controllers, read-only ones included, and other privileged computers can only be changed or deleted by someone holding every permission. - Units, groups and computers can only be created in, or moved to, a parent inside the base DN. The parent used to be whatever DN the request named, so anyone allowed to manage them could write one anywhere the bind account could.
- Failed sign-ins are limited per account as well as per client address: after 5 in 15 minutes, from any number of addresses, the account's attempts are refused with
429until the window ends, without being passed to the directory, so guesses spread over many addresses no longer count towards its lockout there. A successful sign-in clears the count. The limits are the newauth-login-accountrow on the Rate limiting page. - The console's image sends a Content-Security-Policy that allows nothing but its own origin, along with
Cross-Origin-Opener-Policy,Permissions-PolicyandStrict-Transport-Security. A script injected into the page, from another site or written inline, does not run. - Where the console is served with the API — built with
VITE_API_SAME_ORIGIN=true, as the image is — its sign-in screen no longer offers to change the API address, and an address saved in the browser earlier is ignored. A link that set one could send the next sign-in, password included, to someone else's server. - Every API response says
Cache-Control: no-store, so a session token, directory entries or the audit trail are kept by no cache, together withX-Content-Type-Options,X-Frame-Options,Referrer-Policyand a Content-Security-Policy. TheServerheader is no longer sent. - The API's container runs as the .NET images' unprivileged user, uid 1654, instead of root.
Added
Ldap:ConnectTimeoutSeconds(10) andLdap:OperationTimeoutSeconds(30).- A rate-limited request is answered with
Retry-After.
Changed
- The console is built with React 19, Vite 8 and TypeScript 7, and CI builds it on Node 22. Building it from source now needs Node 20.19 or later, 22 recommended.
- On upgrade: the API no longer runs as root, so whatever it writes to —
/dataand/app/logs— has to belong to uid 1654. Volumes created by 0.1.0 and host directories belong to root; hand them over before starting the new image:sudo chown -R 1654 /srv/nelsar-axia/data /srv/nelsar-axia/logs, with your own paths. The quick start'sinitcontainer does this for its own volumes.
Fixed
- An attempt to change something that an endpoint refused for want of a permission is recorded in the audit trail, as a failure, with who made it and the permission it needed. Only refusals made inside a use case were recorded before, so the commonest one — a permission not held at all — left no trace.
- An account's detail view shows its groups. In a directory without
memberOfit showed none, for accounts that were members, whenever the full listing had been read first. - An account opened from a search shows its login and DN, which read "—".
- The dashboard counts groups and organizational units again; it asked for a page larger than the API serves and showed "API unavailable" for both.
- The audit log's details wrap inside the table instead of running past its edge, and the signed-in user's name in the sidebar is no longer drawn under the theme toggle.