Skip to content

fix: harden encryption, key refresh and error messages - #117

Merged
cernadasjuan merged 6 commits into
masterfrom
fix/sdk-hardening
Nov 5, 2026
Merged

cernadasjuan merged 6 commits into
masterfrom
fix/sdk-hardening

Conversation

@cernadasjuan

@cernadasjuan cernadasjuan commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Item parameters: encrypted as UTF-8, so non-ASCII credentials aren't altered on JVMs with another default charset. updateItem(itemId) no longer throws with encryption enabled.
  • Stored api keys: a key that isn't a readable JWT is reused until the API rejects it, then refreshed once, instead of breaking every later request. A failed refresh returns the original 401/403 with a readable body.
  • Error messages and toString: no longer include the api key, connect token or item parameters. /auth error responses still include the API's message.
  • rsaPublicKey(null): now throws instead of silently disabling encryption. The encryption integration test skips when the key isn't configured.
  • Log4j: the jar no longer ships an empty log4j2.properties, which could replace an application's Log4j configuration.
  • Bumps the version to 1.17.3.

Behaviour changes

  • rsaPublicKey(null) throws IllegalArgumentException.

Test plan

  • mvn -B clean verify: 107 unit tests (10 new) and 41 integration tests pass; the 4 skipped are existing @Disabled tests and the encryption test runs with the key set
  • The jar contains no log4j2.* resource and reports version 1.17.3
  • maven-publish.yml for v1.17.3 is green after merge

Parameters were encoded with the JVM's default charset before encryption, so
non-ASCII credentials were altered wherever that default isn't UTF-8. An item
update without a body, such as updateItem(itemId), threw a NullPointerException
when encryption was enabled; it is now sent as-is.
Reading a stored key's exp claim threw when the key wasn't a JWT or its payload
had a non-string claim, which broke every later request on the client. Such a key
is now reused until the API rejects it, then refreshed once. When the refresh
fails, the original 401 or 403 is returned with its body still readable, instead
of a response that was already closed.
…tring

A successful /auth response that couldn't be parsed was copied into the exception
message and the error log, and that body carries the api key. Error responses
still keep their body in the message. toString on AuthResponse,
ConnectTokenResponse, CreateItemRequest and UpdateItemRequest no longer prints
the key, the token or the item parameters.
rsaPublicKey(null), for example from an unset environment variable, silently
built a client without parameter encryption. The integration test that uses the
key now skips when the key isn't configured.
The jar included an empty log4j2.properties. Log4j looks for that file before
log4j2.xml, yaml or json, so it could replace an application's own logging
configuration.
Also documents how the api key interceptor handles keys it can't read,
and that the encryption integration test is skipped without an RSA key.
@cernadasjuan
cernadasjuan marked this pull request as ready for review November 5, 2026 23:33
@cernadasjuan
cernadasjuan merged commit 9c92d0a into master Nov 5, 2026
5 of 6 checks passed
@cernadasjuan
cernadasjuan deleted the fix/sdk-hardening branch November 5, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant