Tika gRPC

This section covers using Apache Tika via gRPC.

Overview

Tika gRPC provides a high-performance gRPC interface for parsing documents. This is useful for microservices architectures and polyglot environments.

The service definition lives in tika-grpc/src/main/proto/tika.proto. Clients register a fetcher (SaveFetcher) and then submit FetchAndParseRequest messages, each of which returns a FetchAndParseReply with extracted metadata and content.

Security

The primary rule is trusted callers only. Treat tika-grpc as a privileged, trusted-network-only service — it is even more exposed by default than tika-server. By default it has no transport security and no per-caller authorization, and its core FetchAndParse surface is always on: anyone who can reach the gRPC port can fetch and parse whatever the server’s configured fetchers can reach.

Its most dangerous capabilities — runtime mutation of the fetcher/iterator store (for example SaveFetcher, which can read files and load code on the server host) and per-request parse configuration — are off by default, behind the flags in Capability Flags, mirroring tika-server’s default-deny capability flags (allowPipes, allowPerRequestConfig). Those flags are defense in depth, not security boundaries — they reduce what a caller can reach but are not a substitute for network controls and mutual TLS, and they do not make it safe to expose tika-grpc to untrusted callers. Run tika-grpc only behind strict network controls.

Capability Flags

Like tika-server, tika-grpc locks down its dangerous capabilities by default. The two flags below live in the grpc section of your tika-config and both default to false. Out of the box, the server only fetches and parses using the fetchers and pipes iterators declared in the config file, using the server’s own parse configuration.

Setting Description

allowPerRequestConfig

When true, callers may attach per-request configuration to FetchAndParse requests (parse_context_json and additional_fetch_config_json), overriding the server’s defaults for that request. Because this can reconfigure any pipeline component (fetcher, parser, timeouts, …​), it is off by default. When false, a request carrying either field is rejected with PERMISSION_DENIED.

allowComponentManagement

When true, callers may manage fetchers and pipes iterators at runtime: add, modify, or delete them (SaveFetcher, DeleteFetcher, SavePipesIterator, DeletePipesIterator), and read their stored configuration back (GetFetcher, ListFetchers, GetPipesIterator). It is off by default for two reasons: mutations change what the server can reach for all subsequent requests (for example, adding a fetcher that escapes a configured base path), and the stored configs returned by the read RPCs may contain secrets (passwords, access keys, tokens). When false, the mutating RPCs are rejected with PERMISSION_DENIED, and the read RPCs return only component identity (id and class), never the config.

Enable these only for trusted callers over a secured channel:

{
  "grpc": {
    "allowPerRequestConfig": true,
    "allowComponentManagement": true
  }
}

Transport Security (TLS)

By default the gRPC server runs without TLS: connections are plaintext and unauthenticated. This includes the apache/tika-grpc Docker image, whose entrypoint does not pass --secure. Only run in this mode on a trusted network.

Transport security is configured entirely through command-line flags (there is no JSON config for gRPC TLS), with three modes:

Insecure (default). No --secure flag. Plaintext, no authentication.

Server (1-way) TLS. Enable -s/--secure and supply the server certificate and key. The server authenticates to clients; clients are not authenticated.

java -jar tika-grpc-<version>.jar --secure \
  --cert-chain server.pem --private-key server.key

Add --private-key-password if the private key is encrypted.

Mutual (2-way) TLS. Additionally supply the trust collection (the CA used to verify client certificates) and require client authentication:

java -jar tika-grpc-<version>.jar --secure \
  --cert-chain server.pem --private-key server.key \
  --trust-cert-collection ca.pem --client-auth-required

Mutual TLS is opt-in: --client-auth-required is off by default, so it has no effect unless --trust-cert-collection is also given (a missing or non-existent trust-collection path is silently ignored). The default port is 50052 (-p/--port).

When running the Docker image, append these flags to the container command — they are forwarded to the server — and mount the certificate files into the container.

Kubernetes and Service Meshes

Running tika-grpc in Kubernetes does not make it safe on its own. By default, pod networking is flat: any pod can reach any other pod’s port, traffic is unencrypted, and there is no authentication or authorization between pods. Kubernetes gives you the tools to lock this down, but none of them are applied automatically. Two distinct controls are involved, and both matter:

  • Transport security. A service mesh (for example Istio or Linkerd) with sidecar mTLS encrypts and authenticates pod-to-pod traffic. If the mesh provides this, you can run tika-grpc without --secure and let the mesh handle transport security in place of the TLS flags above.

  • Reachability. A NetworkPolicy that admits only your trusted client(s) to the tika-grpc Service. This is the control that actually mitigates the exposure described above: because tika-grpc has no per-caller authorization, the set of pods that can reach the port is effectively the set of pods that can use its enabled RPC surface.

Mesh mTLS authenticates who opened the connection; it does not authorize what that caller may do, so an authenticated-but-untrusted pod can still invoke whatever RPC surface is enabled — at minimum FetchAndParse against your configured fetchers, and the runtime component-management RPCs too (including the config reads that can expose stored secrets) if you have set allowComponentManagement. Restricting reachability with a NetworkPolicy is therefore required, not optional — running in Kubernetes without one leaves tika-grpc reachable by every pod in the cluster.

Per-Request ParseContext

FetchAndParseRequest.parse_context_json lets the caller override the server’s default ParseContext on a per-request basis. Keys are parse-context component names; values are their JSON configs.

{
  "basic-content-handler-factory": {"type": "HTML"},
  "timeout-limits": {"progressTimeoutMillis": 30000}
}

See META-INF/tika/parse-context.idx (generated at build time from @TikaComponent annotations) for the available component names.

Per-request configuration is disabled by default. A request that sets parse_context_json (or additional_fetch_config_json) is rejected with PERMISSION_DENIED unless allowPerRequestConfig is enabled. See Capability Flags.

Topics