# Apicurio Registry and the case for running your own API and schema registry

> Apicurio Registry is a Quarkus based service that stores and retrieves API and schema artifacts. Its README is unusually precise about versioning, image tags and OIDC configuration, and unusually silent about how you pick a durable storage backend.

**Apicurio/apicurio-registry** — An API/Schema registry - stores APIs and Schemas.

- Repository: https://github.com/Apicurio/apicurio-registry
- Website: https://www.apicur.io/registry/
- Stars: 945 · Forks: 645
- Language: Java
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/apicurio-apicurio-registry

## A registry that stores and retrieves artifacts, and nothing else

Apicurio Registry stores and retrieves API and schema artifacts. That single sentence is the project's own description, and most of the design follows from it. The artifacts it holds are the contract descriptions that separate teams agree on before any of their code runs: an API description, a schema, a reference to one of those. A team with such documents needs a place where other people can fetch the current version, and a platform group needs one place where those identifiers resolve to content.

That audience is narrower than the name suggests. A registry is not a gateway, not a proxy and not a documentation site. It takes artifacts in and hands them back. The examples directory in the repository names the intended contexts: a gitops setup, an event-driven architecture, Kafka order processing, a Maven plugin carrying TLS credentials, a developer basic auth example, and an MCP example backed by Keycloak. Those are the situations the project was built around, and they all involve teams already deploying containers and already arguing about artifact versions.

The primary language is Java. The licence field on the repository says Apache-2.0, and the README states that Apicurio Registry is a Cloud Native Computing Foundation Sandbox project, with the copyright held by a Series of LF Projects, LLC. Developer and security mailing lists are published on lists.cncf.io, and community discussion happens on the CNCF Slack channel.

## Building from source needs JDK 21 while the artifacts still target 17

The registry runs on Quarkus. The quickest path described in the README builds it from source with the in-memory storage variant, and it starts with an unusual requirement split: JDK 21 or newer is required to build the project, because the build tooling such as Checkstyle needs a Java 21+ runtime, while the produced artifacts still target Java 17.

That detail matters more than it first appears. A continuous integration image can build on 21 and ship a runtime that still starts on a Java 17 base image, which keeps the deployment footprint conservative. A team that assumes the build JDK equals the runtime JDK will pick the wrong base image.

Here is the full sequence the README gives for a first local run.

```bash
./mvnw clean install -Dlocal -DskipTests
cd app/
../mvnw quarkus:dev -Dlocal
```

The Maven wrapper script is checked into the repository, so the first command builds with the project pinned wrapper rather than a system Maven. The second command changes into app/ and calls the wrapper one directory up, which is why the path jumps back a level. When the process settles, the README says to expect Quarkus and the in-memory registry to have started, with the REST APIs available on localhost port 8080 and the API documentation served at http://localhost:8080/apis. In-memory storage means the state disappears when the process stops, which is precisely what you want for a first look and precisely what you do not want for anything shared with other teams.

## The user interface is a second application on a second port

The web interface is not part of the registry process. It is a separate frontend application that the README starts in development mode from the ui directory, and it listens on port 8888 while the API stays on 8080.

```bash
cd ui
npm install
cd ui-app
./init-dev.sh
npm run dev
```

The init-dev.sh step is the one worth understanding, because it is the only part of the flow that the README does not spell out beyond naming the script. The UI README is cited for the details.

For deployments, the same split exists in the published container images. Pre-built images are published to Docker Hub for every commit to main, and there are two of them, one for each half.

```bash
docker run -it -p 8080:8080 apicurio/apicurio-registry:latest-snapshot
```

```bash
docker run -it -p 8888:8080 apicurio/apicurio-registry-ui:latest-snapshot
```

Note the port mapping in the second command: the UI container serves on 8080 inside the container and the host publishes it on 8888. Reading that line as a copy of the first one and changing only the image name is an easy mistake. Running the two containers separately also means the UI can be scaled or hidden independently of the API, and it means an operator can leave the UI off entirely if the registry is only consumed over HTTP by build pipelines.

## OIDC configuration differs between the REST API and the interface

Authentication is off by default and enabled through an OpenID Connect server. The same server and the same users are federated across the interface and the REST APIs, so one set of credentials works for both halves. The configuration itself, however, is not shared, and this is where a first deployment usually stalls.

The REST API takes three environment variables:

```bash
QUARKUS_OIDC_TENANT_ENABLED
QUARKUS_OIDC_AUTH_SERVER_URL
QUARKUS_OIDC_CLIENT_ID
```

The interface takes a different set:

```bash
REGISTRY_AUTH_TYPE
REGISTRY_AUTH_URL
REGISTRY_AUTH_REDIRECT_URL
REGISTRY_AUTH_CLIENT_ID
```

The first API variable defaults to false and the interface variable REGISTRY_AUTH_TYPE defaults to none, so an unprotected deployment is the out-of-the-box state and enabling access is a deliberate act. The README also states a hard ordering constraint: everything must be configured in the OIDC provider before starting the application. Miss that and the failure appears at startup rather than as a denied request.

The README is careful to frame both tables as a starting point, noting that the registry supports a much wider range of authentication and authorization options than shown here and pointing to the security documentation for the full picture. Authentication is the easy half. Authorization, who may write which artifact type and who may read it, is the half that decides whether the service is safe to expose, and the README hands that off to an external document rather than describing it.

## Patch releases carry security fixes only, and two minors stay supported

Apicurio Registry follows Semantic Versioning, but the split between release kinds is stricter than most projects adopt. Minor releases such as 3.3.0 and 3.4.0 carry new features, enhancements and bug fixes. Patch releases such as 3.3.1 and 3.3.2 carry CVE and security fixes only, with no new features and no bug fixes at all.

That constraint shapes upgrade planning. Moving from 3.3.1 to 3.3.2 within a minor line is a security-only step, which is the low-risk way to keep a deployment current. Moving from 3.3.x to 3.4.x is a feature release and needs the normal regression pass, even if your usage is narrow. The recent release dates, 3.3.1 on 2026-07-27, 3.3.2 on 2026-08-27 and 3.3.3 on 2026-09-08, show the patch line moving roughly once a month without a stated schedule, so the two most recent minors are the ones to watch.

Support is bounded at two minor versions, latest and latest-1, and older minors are declared end-of-life. The Kubernetes side follows the same numbering: each minor version has its own OLM channel, and a rolling 3.x channel is available for operators who want the newest minor immediately.

The published images follow the release numbering with four distinct kinds of tag:

```bash
3.3.0
3.3
latest
latest-snapshot
```

A pinned tag such as 3.3.0 fixes the exact release. The floating 3.3 tag always points to the latest patch in that series. The latest tag points to the most recent stable release. The latest-snapshot tag is the most recent build from the main branch and is described as unstable, which makes it a development convenience rather than something to deploy. The repository is not archived, and the last push was on 2026-10-19.

## Picking a storage backend is the decision the README punts on

The in-memory variant is a development convenience, and the README does not dress it up as anything else. For the full set of runtime configuration options, covering storage and deployment among others, the README sends readers to the online documentation site instead of listing them.

So the practical first question for anyone evaluating this project is which storage variant a production deployment should use, and the README does not answer it. That is a genuine gap, and it is the gap worth closing before anything else, because the choice determines whether artifacts survive a restart, whether you operate a database, and how far the horizontal scaling story goes. The registry also carries a sibling layout that hints at breadth: the top level of the repository contains schema-resolver/, schema-validation/, serdes/, common/, config-index/ and schema-util/, which is a much larger surface than a single store and retrieve service.

The alternative approach is worth weighing against the registry as a service. Several example directories, including avro-maven-with-references/, avro-maven-with-references-auto/, maven-plugin-tls-credentials/ and json-maven-with-references/, show artifacts distributed and resolved through a build tool instead of fetched from a running registry. The difference in approach is real: the build-time route needs no long-running service, no artifact identifiers to keep straight and no separate authentication surface, at the cost of resolving at compile time rather than discovering the newest version at runtime. The registry route gives you one addressable store with an HTTP API and OIDC in front of it, at the cost of an operational dependency and an availability question. Which one fits depends on whether your consumers need the newest artifact at request time or can accept a version pinned at build time.

## SDKs, a CLI and an operator exist, but only one of them is documented

The top level of the repository is considerably wider than the README. Alongside the application, the common and schema modules and the examples, it contains cli/, go-sdk/, java-sdk/, python-sdk/, mcp/, operator/, install/, distro/, adr/, integration-tests/, perf-tests/, perf-comparison-tests/, ide-config/ and scripts/. There is also a console-plugin/ directory, which is a strong hint that registry content is surfaced inside a developer console rather than only through a browser page.

The README covers almost none of this. It points to DEVELOPING.md for build setup, IDE configuration and testing, to CONTRIBUTING.md for contribution guidelines, and to the online documentation for runtime configuration, security and deployment. The only concrete statement about the operator is the OLM channel note. There is no README section for the command line client, for the three language SDKs or for the MCP server, and no stated compatibility range between those clients and a given registry release.

The consequence for an evaluator is narrow but real. The registry itself is well described, and its versioning, image tags and authentication variables are precise enough to plan a deployment against. The client surface is not. Before committing to a particular SDK or CLI, you would need to open that directory's own documentation, because the project overview gives you no basis for choosing one over another.

## Conclusion

Adopt Apicurio Registry if your team already runs containers and wants one self-hosted place to store and retrieve API and schema artifacts, and if you can supply an OIDC provider and a durable storage configuration before real traffic arrives. Skip it if all you need is schema references resolved at build time, because the repository ships Maven examples that do exactly that without a running service. Before the first production deployment, verify which storage variant you configured, what the authorization model looks like beyond the three variables named in the README, and which patch release you intend to pin.

## FAQ

### How do I run Apicurio Registry locally for development?

Build it with JDK 21 or newer using `./mvnw clean install -Dlocal -DskipTests`, then start the Quarkus dev mode from the app directory with `../mvnw quarkus:dev -Dlocal`. The REST APIs are then available on localhost port 8080, with API documentation served at http://localhost:8080/apis.

### How do I enable authentication on the Apicurio Registry REST API?

Set `QUARKUS_OIDC_TENANT_ENABLED` to true and then supply `QUARKUS_OIDC_AUTH_SERVER_URL` and `QUARKUS_OIDC_CLIENT_ID`. The OIDC server and its users are federated across the REST APIs and the user interface, and everything must be configured in the OIDC provider before the application starts.

### Which Apicurio Registry Docker image tag should I use for a deployment?

Use a pinned tag such as `3.3.0` for an exact release, or the floating `3.3` tag to always get the latest patch in that series. The `latest` tag points to the most recent stable release, while `latest-snapshot` tracks a build from the main branch and is described as unstable.

### How long are Apicurio Registry releases supported?

The two most recent minor versions, latest and latest-1, receive patch releases for security issues, and older minors are end-of-life. Patch releases contain CVE and security fixes only, with no new features and no bug fixes.

## Sources

- [Apicurio/apicurio-registry on GitHub](https://github.com/Apicurio/apicurio-registry)
- [License: Apache-2.0](https://github.com/Apicurio/apicurio-registry/blob/main/LICENSE)
- [Project website](https://www.apicur.io/registry/)
- [README](https://github.com/Apicurio/apicurio-registry/blob/main/README.md)
- [Releases](https://github.com/Apicurio/apicurio-registry/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apicurio-apicurio-registry
