Kotlin and JVM SDK
Three modules (JVM 17+). Not on Maven Central yet (they will be at the public release): install them into your local Maven repository and depend on them from your services.
cd sdk/kotlin && ./gradlew publishToMavenLocal// your service's build.gradle.ktsrepositories { mavenLocal(); mavenCentral() }dependencies { implementation("io.github.burakmetehan.authbase:authbase-ktor:0.1.0") // Ktor implementation("io.github.burakmetehan.authbase:authbase-spring-boot-starter:0.1.0") // or Spring Boot}| Module | What |
|---|---|
authbase-core |
Authbase (suspend client for the end-user API) and AccessTokenVerifier |
authbase-ktor |
a Ktor Authentication provider and requireRoles |
authbase-spring-boot-starter |
auto-configured client, Spring Security JwtDecoder, roles → ROLE_… |
The client
Section titled “The client”One per app, with its API key from the environment (never in code):
val authbase = Authbase(url = System.getenv("AUTHBASE_URL"), apiKey = System.getenv("AUTHBASE_API_KEY"))
authbase.users.create(CreateUserRequest(email = email, password = password))val tokens = authbase.auth.login(LoginRequest(identifier = email, password = password, clientIp = ip))val next = authbase.auth.refresh(RefreshRequest(refreshToken = tokens.refreshToken))authbase.users.update(userId) { roles = listOf("admin"); username = null } // sends only these; null clearsCalls are suspend and throw AuthbaseException on a non-2xx answer:
status, code (branch on this), detail, requestId, errors (per
field, for 422), retryAfter (429/503). An unreachable server is
code = "network_error".
Verifying access tokens
Section titled “Verifying access tokens”Offline, against the app’s JWKS: fetched once, cached for 5 minutes,
refetched (at most once a second) for an unknown kid, so a signing-key
rotation needs no restart. Only EdDSA, typ: at+jwt, the app’s issuer
and the app id as aud are accepted. Ed25519 is verified with the JDK’s
own implementation (Java 15+), so no Tink or BouncyCastle is pulled in.
val claims = authbase.verifyAccessToken(token) // learns issuer and app id from the API key, onceval verifier = AccessTokenVerifier(VerifierOptions(issuer = "https://auth.example.com/apps/cashmate", appId = "01a0…"))A bad token throws AuthbaseTokenException (reason: MISSING,
EXPIRED — worth a refresh — or INVALID); an unreachable JWKS throws
AuthbaseUnavailableException, an outage rather than the caller’s fault.
install(Authentication) { authbase { client(authbase) } } // or verifier(VerifierOptions(issuer, appId))routing { authenticate("authbase") { get("/me") { call.respond(call.authbase!!.subject) } requireRoles("admin") { delete("/posts/{id}") { /* … */ } } }}401 (WWW-Authenticate: Bearer, RFC 6750) for a missing or bad token, 403
for missing roles, 503 when the JWKS cannot be fetched; bodies are
problem+json.
Spring Boot
Section titled “Spring Boot”Add spring-boot-starter-security-oauth2-resource-server and set either
the client’s properties or the verifier’s:
authbase.url=https://auth.example.comauthbase.api-key=${AUTHBASE_API_KEY}# or, to verify without an API key:# authbase.issuer=https://auth.example.com/apps/cashmate# authbase.app-id=01a0…@Beanfun security(http: HttpSecurity): SecurityFilterChain = http .authorizeHttpRequests { it.requestMatchers("/admin/**").hasRole("admin"); it.anyRequest().authenticated() } .oauth2ResourceServer { it.jwt { } } .build()The starter supplies the JwtDecoder (authbase’s verifier) and maps the
roles claim to ROLE_… authorities; @AuthenticationPrincipal jwt: Jwt
gives the claims (jwt.subject is the user id). An Authbase bean is
there for calls; its methods are suspend, so Spring MVC controllers that
call them need org.jetbrains.kotlinx:kotlinx-coroutines-reactor (Spring
runs suspend handlers through Reactor). Define your own bean of any of
these types to replace it.
Development
Section titled “Development”./gradlew build compiles (warnings are errors), tests and packages every
module. ModelsMatchSpecTest fails when a model’s fields drift from
api/openapi/openapi.yaml. AUTHBASE_TEST_URL=http://localhost:8080 ./gradlew test also runs the integration test against a real instance.
For agents: this page as markdown · llms.txt