Skip to content

Languages

tacplus targets seven languages in three tiers. The tier decides what a build may generate: a client-only target given a proto that asks for service-side output rejects the build loudly instead of emitting a partial server.

Tier Languages Status
Full service Go, Rust, Java Every surface, server and client, at parity across the three. Go and Rust lead; Java is close behind.
Full client TypeScript, Python Every client surface with client-side validation. No server runtime, by design.
Lite client Swift, C# C2S, W2S and C2D clients. Compiled in CI, not yet exercised against a live server.

What each language gets

yes   partly (see notes)   not generated

Go Rust Java TypeScript Python Swift C#
Protobuf message types
Validation from assert_* annotations1
Handler interface and server wrapper
MCP tools for user-facing rpcs
ServiceManager runtime (identity, TLS, health, lifecycle)
State service and typed state accessors
S2S clients (service to service)
C2S clients (client to service, native gRPC)
W2S clients (web to service)2
REST clients
C2D clients (client to local daemon)
C2D server (hosting a local daemon)
Client identity manager (client_im)
Formal-verification harness for assert_invariant3

Which clients a build emits is decided by the proto, not by tacplus.yaml: a grpc_c2s_client dependency produces a C2S client, a grpc_w2s_client dependency a W2S client, and a service_c2d service a C2D client. See client transport surfaces.

Generated packages

Each build writes one package in the target's own packaging, named from the pkg in tacplus.yaml (the rules are in the user guide):

Language Package pkg: com.example.identity becomes
Go Go module example.com/identity/model
Rust Cargo crates identity-model
Java Maven sources com.example.identity.model
TypeScript npm package identity-model
Python pyproject.toml package identity_model
Swift Swift package (SwiftPM) IdentityModel
C# .NET project IdentityModel

Full service: Go, Rust, Java

The three server backends generate the full service: types and validation, the handler interface and the wrapper around it (authentication, authorization, validation, namespace policy, tracing and accounting, status mapping), MCP dispatch, the state service and accessors, the ServiceManager runtime and its libraries, and every client surface. None of them is the reference implementation: the contract is the annotated proto plus the generated API, and a feature added to one server language is added to all three. The cross-language gates in the repository hold them to it.

Full client: TypeScript, Python

The full-client targets generate every client surface (C2S, W2S, C2D and REST) with the same request validation the servers run, so an invalid request fails in the client with the server's own message. Asking them for anything service-side (S2S clients, server wrappers, ServiceManager, EventBus runtime, health, service state or stores) fails the build.

Lite client: C# and Swift

The lite targets generate C2S, W2S and C2D clients for apps that call tacplus services. Swift emits a SwiftPM package whose C2D client dials a Unix-domain socket; C# emits a .NET project whose C2D client uses named pipes on Windows and Unix-domain sockets elsewhere, and whose protobuf code comes from Grpc.Tools in your own dotnet build. For streaming methods they cannot carry, and for request validation, use a Go, Java or Rust client.


  1. Server languages validate inbound and outbound at every service boundary; client languages validate a request before sending it. Swift and C# currently emit no client-side request validation and no default request deadline. ↩

  2. W2S carries unary calls over HTTP/REST, server streaming over SSE, and client and bidi streaming over WebSockets. Swift carries unary and server-streaming methods; C# carries unary methods only. A method the target cannot carry is emitted as a compile-time-unavailable stub, so a mixed service still compiles and no declared method disappears. ↩

  3. Rust harnesses are Kani proofs, Java harnesses are JBMC proofs; tacplus verify runs them. ↩