CleverITSPLA API
More
v1.2.0

Security

How the SPLA API protects logins, data and the monthly report. Written for security reviewers and for anyone who wants to know what happens with their password.

Short version

What is stored where

Data Where How long
Password, client secret Nowhere. Used once to call CloudIQ, then dropped with the request. Duration of the login request
CloudIQ access token Process memory, inside the session Until the session ends (max 55 min, idle 30 min, logout, restart)
Session token Only its SHA-256 hash, as key of the session table in memory Same
User name, organization ids Session (memory) and audit log Audit log: 13 months
Report contents Not stored. Passed through from CloudIQ per request. -
Audit events /var/log/spla-api/audit.log 13 monthly files

There is no database. A restart forgets all sessions.

Login

Sessions

Authorization

Changes to CloudIQ

Input checks

Rate limits

Per IP: 20 login attempts per 10 minutes, 300 requests per minute (shared by everyone behind one office or RD address). Per user name: 5 failed logins per 15 minutes, and at most 2 logins running at the same time (so simultaneous guesses cannot pass the failure limit; successful logins are not limited). Per session: 120 requests per minute and at most 2 at the same time. For the whole service: at most 100 failed password logins per 10 minutes (setting SPLA_API_LOGIN_FAILURES_GLOBAL_PER_10MIN); while that ceiling is reached, password logins of user names that have not logged in successfully through this service in the last 60 days are refused. On the public name, nginx in front of the service also allows 10 requests per second per address (bursts of 40) and 20 open connections per address. Answers 429 with Retry-After.

Trade-offs of the limits on a public service: someone can block a user name in this service for 15 minutes with five wrong passwords. Someone with many addresses can keep the service-wide ceiling reached for as long as they keep trying; then new user names cannot log in with a password, but user names that logged in through this service in the last 60 days keep working (still with their own limit of 5 failures), and logins with your own access token (option B) are never under the ceiling: a token cannot be guessed. Nothing here locks the CloudIQ account. The ceiling exists so that the service can never be used to try passwords against SoftwareOne at scale, and so that SoftwareOne has no reason to block this server. The audit log shows it (rate_limited, scope login_failures_global); watch for it. The list of known user names is kept as SHA-256 hashes in /var/lib/spla-api/known-users.json (readable only by the service, at most 10,000 entries, 60 days). The hashes are not salted: someone who can read the file and guesses a user name can check whether it logged in. The file holds no passwords, tokens or other data. While the ceiling is reached, the answer differs for known user names (CloudIQ is asked: 401 or 201) and unknown ones (429), so someone could learn which user names logged in through this service recently; each such check still costs that user name one of its 5 allowed failures. Accepted: user names are not secret, and the alternative would lock out known partners.

Network and TLS

Web pages: Try it and the API reference

Logging

Running it

Known limits and residual risks

Risk Status
CloudIQ API login has no second factor SoftwareOne design. Mitigated by limits (also service-wide), option B, separate API clients.
Public: anyone can try to log in Same exposure as SoftwareOne's own public API; limits per address, per user name and service-wide (see Rate limits).
Public: the service-wide login ceiling can be kept reached on purpose New user names cannot log in with a password meanwhile; known user names (last 60 days) and option B keep working; visible in the audit log (rate_limited, scope login_failures_global).
Public demo used to fill memory Every login has its own copy with at most 40 reports; at most 1000 logins are kept (about 50 MB); the fake CloudIQ restarts on its memory cap, which only logs out demo users.
Audit log keeps the user names of failed logins from anyone Needed to see attacks; shortened to 100 characters, kept 13 months. A password typed into the user-name field would be logged; the login answer never echoes it.
Self-signed certificate on the internal ports Internal clients trust exactly this certificate (no -k); the public name has a Let's Encrypt certificate.
Add/remove line overwrites concurrent portal edits Documented; quantity changes use a row-level PATCH that does not have this.
Someone submits the draft in the portal between our check and our change CloudIQ offers no version field to lock on. The report is read again just before and right after each change, and a report that is no longer a draft is not changed. Whether CloudIQ itself refuses changes to a submitted report is not tested (no live writes so far).
Write calls tested only against the fake CloudIQ Writes are off in production until tested live with the owner watching.
Sessions lost on restart Accepted: users log in again.
Root and nginx on the server can reach the sockets directly Inherent; the server is managed by CleverIT only.
Outgoing traffic is not limited to CloudIQ addresses CloudIQ addresses can change; possible later with IPAddressAllow= in the unit.

Reporting a problem

Report suspected vulnerabilities to your contact at CleverIT, with the time and request_id, or e-mail support@cleverit.nl. Please do not test against production with real reports; use the demo (/demo).