Skip to content

Java SDK: Batch Check does not pass Authorization Model Id in body. #551

@yatesdev

Description

@yatesdev

Checklist

  • I have looked into the README and have not found a suitable solution or answer.
  • I have looked into the documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have searched the Slack Community and have not found a suitable solution or answer.
  • I agree to the terms within the OpenFGA Code of Conduct.

Description

When making a batch check request via the Java SDK, the authorization model id is not added into the request body, forcing the API to query the DB for the latest model.

The authorizationModelId is defined as a property on dev.openfga.sdk.api.configuration.ClientBatchCheckOptions, but the SDK isn't using it, compared to say, the singular check function.

I'd be happy to take a shot at submitting a PR for this, in it's current form it appears a simple enough fix.
However, brainstorming on it from a library perspective I wonder if there is a more involved fix. Mainly, should batch checks be allowed to query against multiple authorization models in the same request? If so, that would require moving the authorization_model_id into the list of checks. Probably not worth the complexity tradeoff.

Expectation

Authorization Model Id is included in the BatchCheck request body to align with the API documentation.

Reproduction

Attached is the Kotlin Script file I used for isolating if the issue was SDK related:

Minimal authorization model

model
  schema 1.1

type user

type company
  relations
    define can_read: [user]
import dev.openfga.sdk.api.client.OpenFgaClient
import dev.openfga.sdk.api.client.model.ClientBatchCheckItem
import dev.openfga.sdk.api.client.model.ClientBatchCheckRequest
import dev.openfga.sdk.api.configuration.ClientBatchCheckOptions
import dev.openfga.sdk.api.configuration.ClientConfiguration
import dev.openfga.sdk.api.model.ConsistencyPreference
import java.util.UUID

val client = OpenFgaClient(
    ClientConfiguration().apply {
        apiUrl("http://localhost:8089")
        storeId("01JD8HRYRBJCASPHNVHKXYSP55")
    }
).apply {
    setAuthorizationModelId(this.readLatestAuthorizationModel().get().authorizationModel?.id)
}

val latestAuthorizationModelId = client.readLatestAuthorizationModel().get().authorizationModel?.id

val options = ClientBatchCheckOptions().apply {
    authorizationModelId(latestAuthorizationModelId) // This value is not being passed into the request
    consistency(ConsistencyPreference.MINIMIZE_LATENCY)
}

val body = ClientBatchCheckRequest().apply {
    checks(
        listOf(
            ClientBatchCheckItem().apply {
                user("user:1")
                relation("can_read")
                _object("company:1")
                correlationId(UUID.randomUUID().toString())
            }
        )
    )
}

val response = client.batchCheck(body, options).get()

Then checked OpenFGA Logs...

SDK Checklist

  • JS SDK
  • Go SDK
  • .NET SDK
  • Python SDK
  • Java SDK

OpenFGA SDK version

v0.8.1

OpenFGA version

v1.8.6

SDK Configuration

Spring Boot bean with a configuration class

Logs

2025-05-27 11:03:33 2025-05-27T16:03:33.671Z    INFO    grpc_req_complete       {"grpc_service": "openfga.v1.OpenFGAService", "grpc_method": "BatchCheck", "grpc_type": "unary", "user_agent": "openfga-sdk java/0.8.1", "raw_request": {"store_id":"01JD8HRYRBJCASPHNVHKXYSP55","checks":[{"tuple_key":{"user":"user:1","relation":"can_read","object":"company:1"},"contextual_tuples":null,"context":null,"correlation_id":"74116a59-52ae-489d-a958-4d983f1dfc46"}],"authorization_model_id":"","consistency":"UNSPECIFIED"}, "raw_response": {"result":{"74116a59-52ae-489d-a958-4d983f1dfc46":{"allowed":false}}}, "query_duration_ms": "5", "peer.address": "127.0.0.1:52760", "request_id": "8b374bde-92e5-4fd4-ab20-911a6e75c9f6", "store_id": "01JD8HRYRBJCASPHNVHKXYSP55", "authorization_model_id": "01JVWFWBNBY8KNYVXRY511BB8Z", "duplicate_checks": 0, "datastore_query_count": 4, "grpc_code": 0}

Note that the raw_request.authorization_model_id is empty, while it ultimately is hitting the DB to fetch the latest in raw_response.authorization_model_id

References

What appears to be missing from the batchCheck is this code segment from check

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions