Data handling and security
A precise description of how the connection service handles tokens, and the protections around it, for security reviewers.
Summary#
The connection service passes a person's authorization result from a provider to the installation that asked for it. It keeps nothing beyond a sealed, single-use hand-off record that is accepted for at most 5 minutes. It never reads the content of connected accounts. This page is for security and compliance reviewers; the Privacy Policy covers the same facts in policy form.
The connection flow#
- The installation sends the person's browser to the service, naming the provider, a return address, an opaque attempt value, the permissions needed and a one-way challenge (a SHA-256 fingerprint of a secret that stays in the installation).
- The service validates every field, then redirects the browser to the provider with a signed state value. The signed state carries the provider, an expiry, a one-time nonce, the challenge, the attempt value and the return address.
- The service records the one-time nonce for at most 10 minutes.
- The person approves access at the provider, which redirects the browser back to the service with an authorization code.
- The service verifies the signed state, takes the nonce (so a replay finds nothing), and exchanges the code for tokens at the provider using the service's own client credentials.
- The service seals the result, stores the sealed record under a random 256-bit identifier, and redirects the browser to the installation with only that identifier and the attempt value.
- The installation's server presents the identifier and its secret to the service. The service deletes the record, checks the secret against the challenge and returns the result. The browser never sees a code or token.
What is sealed, and for how long#
- The result is encrypted with AES-GCM before it is stored. The key is held in a managed secrets store and delivered to the running service as a secret, never written into the task definition or the image.
- The hand-off identifier is bound to the ciphertext as associated data, so a sealed record copied to another identifier does not open.
- The database holds only the ciphertext, encrypted at rest. The table has no backups.
- The sealed result is accepted for at most 5 minutes. The pending-attempt nonce is accepted for at most 10 minutes.
- The record is deleted on the first attempt to collect it, whether or not that attempt succeeds. A wrong secret burns the record.
- After 5 minutes (10 for a nonce) a record is rejected on read. The database then removes expired records physically; Amazon Web Services documents that it deletes expired items "typically within a few days after their expiration". Until removal a record remains encrypted.
Refreshing a connection#
The installation holds both tokens and sends the refresh token to the service. The service adds its client credentials, refreshes at the provider and returns the new tokens in the response. It stores nothing: no record, no nonce, no copy of either token.
Transport security#
- Every connection to the service uses HTTPS. Plain HTTP requests are redirected to HTTPS at the load balancer.
- In production the service sends an HTTP Strict Transport Security header with a one-year lifetime that includes subdomains.
- Responses carry a strict Content Security Policy, a no-sniff header and frame restrictions. Connection routes are never cached.
Web firewall#
A web application firewall sits in front of the service:
- A per-address rate limit of 2,000 requests per five minutes.
- AWS managed rule sets: Common, Known Bad Inputs, SQL Injection and Amazon IP Reputation.
- A country allow-list for the United States, Canada and the member states of the European Union. The connection routes are exempt from the country allow-list, because people and installations that use them can be anywhere; the rate limit and managed rule sets still apply to them.
Request validation#
- The state value is signed with HMAC-SHA256 and expires after 10 minutes.
- The return address must be an HTTPS address with no embedded credentials and no fragment, within a length limit and a strict character set.
- Each nonce is single use.
- Requested permissions must be a subset of what the service allows for that provider.
- Failures at collection are uniform: an unknown, expired, replayed or wrong-secret request all receive the same response, so nothing is revealed about which one occurred.
- A failed callback shows a plain error page and never redirects.
Logging and tracing#
Logs contain the request path, method, status, duration, provider name, outcome and stable error codes or types. They never contain tokens, authorization codes, client secrets, handoff identifiers, verifier secrets, keys or query strings. Request tracing excludes the connection routes, and any query string is removed from trace data if one is ever recorded. Logs are kept for one month. We have not turned on load balancer access logs or web firewall request logging.
Secrets and access#
- Provider client secrets and the keys for signing and sealing are held in a managed secrets store and are sent only to the provider's token endpoint. They are never sent to an installation or a browser.
- The service runs with an access role limited to reading, writing and deleting records in its single database table and checking that table's status.
Availability#
The service is hosted on Amazon Web Services in the United States, and data is processed only there.
Installations do not depend on the service to run. If it is unavailable, an installation keeps working and offers its own alternative for connecting accounts.
Revoking access#
- In your Workforce Intelligence installation, disconnect the account.
- In the outside service's own account settings (for example a security or connected-apps page), remove the Workforce Intelligence application. This ends access at the provider regardless of what any installation holds.
Reporting a security issue#
Write to privacy@workforceintelligence.ai with the details. Please do not test against the service in ways that affect other people, and give us reasonable time to respond before disclosing publicly.