Skip to content
krynox-securityPublic

About

Official Java SDK for Krynox Captcha — server-side /siteverify verification. MIT.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

krynox-captcha (Java)

Official server-side verification SDK for Krynox Captcha. Java 17+, one small dependency (Gson).

<dependency>
  <groupId>net.krynox</groupId>
  <artifactId>krynox-captcha</artifactId>
  <version>0.1.0</version>
</dependency>
import net.krynox.captcha.KrynoxCaptcha;

KrynoxCaptcha krynox = new KrynoxCaptcha(System.getenv("KRYNOX_SECRET"));

// in your request handler
KrynoxCaptcha.Result r = krynox.verify(token, request.getRemoteAddr());
if (!r.success()) {
  response.sendError(400, "Captcha verification failed");
  return;
}
// optional: privacy-preserving risk hint + explainable reason codes
if ("high".equals(r.risk()) || r.reasons().contains("tor-exit")) {
  // add friction (email verification, manual review, …)
}

Reasons, agents & attested humans

  • r.reasons() — stable codes explaining the score ("tor-exit", "elevated-request-rate", …).
  • r.agent() — non-null when a verified AI agent (Web Bot Auth) was forwarded: .verified(), .name(), .allowlisted(). Allowlist good bots instead of blocking them.
  • r.human() — non-null when a device-attested human (Private Access Token) was forwarded: .attested(), .method(), .issuer().
if (r.agent() != null && r.agent().verified() && r.agent().allowlisted()) { /* trusted crawler */ }
if (r.human() != null && r.human().attested()) { /* proven human, skip friction */ }

Content classification (spam/abuse)

KrynoxCaptcha.Classification c = krynox.classify(comment, clientIp);
// or score a whole form: classifyFields(Map.of("name", name, "message", comment), clientIp)
if (c.blocked() || "BAD".equals(c.classification())) {
  response.sendError(400, "rejected");
}

Reliability

Transient failures (network, 429, 5xx) are retried automatically (default 2, exponential backoff; 4th constructor arg). A retried verify carries an idempotency key so it never fails the single-use token — the server replays the first outcome.

Feedback (false-positive correction)

// a real user got blocked by mistake → un-block their IP
KrynoxCaptcha.Feedback fb = krynox.feedback("human", clientIp, "support ticket #1234");

// confirm a bot you let through
krynox.feedback("bot", suspiciousIp, null);

API

  • new KrynoxCaptcha(secret) or new KrynoxCaptcha(secret, endpoint, Duration timeout[, int retries])
  • verify(response[, remoteip[, idempotencyKey]]) → Result
  • classify(text, ip) / classifyFields(Map<String, String> fields, ip) → Classification
  • feedback(label, ip, note) → Feedback — label is "human" or "bot"

Result: success(), score(), risk(), hostname(), challengeTs(), action(), cdata(), errorCodes(), reasons(), agent(), human() Classification: ok(), score(), classification(), reasons(), blocked(), errorCodes(). Error codes: KrynoxCaptcha.ErrorCode.RATE_LIMITED, etc.

Self-hosting? Pass an endpoint like https://captcha.your-domain/siteverify, or just the base URL https://captcha.your-domain. classify and feedback derive their URLs from it: a /siteverify suffix is replaced, otherwise the path is appended.

Every request carries User-Agent: krynox-captcha-java/0.1.0 (KrynoxCaptcha.USER_AGENT), so API traffic is attributable to SDK and version. Gson stays an implementation detail — it never appears in the public API.

MIT licensed. Docs: https://docs.krynox.net

About

Official Java SDK for Krynox Captcha — server-side /siteverify verification. MIT.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages