Katta: transform your S3 storage into a secure, team-friendly workspace with client-side encryption.
Easily integrates into your S3 storage and existing identity management, including OpenID Connect, SAML, and LDAP.
Katta Server consists of the following components.
During development, run Vite from the frontend directory as explained in its README file.
During development, run Quarkus from the backend directory as explained in its README file.
We add a custom Katta theme to the base Keycloak image, as explained in its README file.
Katta relies on Keycloak's Standard Token Exchange (V2)
as per RFC 8693 to obtain vault-specific tokens for STS/S3 calls. The keycloak
module contains integration tests verifying this setup.
See Katta Documentation → Self-Hosting Guide → Deployment.
See CHANGELOG.md.
This project is licensed under the GNU Affero General Public License v3.0.
Katta Server is a downstream fork of Cryptomator Hub (upstream remote) and regularly merges its develop branch. Everything in this section exists to keep those merges cheap: Katta-specific code stays recognizable and separable, upstream files are changed as little as possible, and the few things that must diverge (brand, images, schema) follow fixed rules.
-
Backend: Katta-only classes go into
kattasub-packages, e.g.org.cryptomator.hub.api.katta,org.cryptomator.hub.entities.katta,org.cryptomator.hub.katta. The root package deliberately staysorg.cryptomator.hubto avoid renaming every upstream file. Only the standalone Keycloak tests usecloud.katta. -
Frontend: Katta-only components go into
frontend/src/components/katta/, shared helpers intofrontend/src/common/katta.tsor a dedicated file. -
Single-line diffs inside upstream files: if the change is obvious (e.g. replacing "Cryptomator Hub" with "Katta Server", swapping an upstream image or artifact name for the downstream one), just make it. If it is not obvious why the line differs (e.g. replacing
i < 3withi < 5), add a short inline comment on the same line, e.g.// katta allows up to five i. Either way, do not add extra lines: the file should stay line-by-line comparable with upstream so the next merge is easy. -
Multi-line diffs inside upstream files: wrap larger extensions in
start katta extension/end katta extensionmarkers so they survive a merge and are easy to find and re-apply. Use the comment syntax of the surrounding language:// / start katta extension ... // \ end katta extension
<!-- / start katta extension --> ... <!-- \ end katta extension -->
Keep the marked block as small as possible and prefer a call into a
kattapackage or file over inline logic. -
Helm chart (
chart/) is Katta's deployment artifact and has its ownCHANGELOG.mdand version. Upstream'sdeploy/directory (Compose files, upstream Helm READMEs) is kept verbatim from upstream and is not adjusted or used by Katta.
Upstream is "Cryptomator Hub", Katta is "Katta". The following places are branded and need a check after every merge, especially when upstream adds a new page or component:
- Logo:
frontend/public/logo.png(upstream shipslogo.svg, which is deleted downstream). Use<img src="/logo.png" alt="Katta Logo">with the sizes used by existing Katta pages (h-9in navigation bars,h-16on centered cards). A build failure "Could not resolve '/logo.svg'" means a newly merged component still references the upstream logo. - Wordmark and title:
KATTAinstead ofCRYPTOMATOR HUBin navigation bars,<title>Katta</title>infrontend/index.html. Headline font is Roboto Slab (frontend/src/css/fonts.css), upstream's Quicksand subset is removed. - Visible strings: "Hub" and "Cryptomator Hub" are replaced by "Katta" in
frontend/src/i18n/en-US.jsonand in the other locale files. Every upstream merge brings new or re-translated strings, so search the i18n files forHubafter merging. Technical identifiers such as JSON keys (admin.serverInfo.hubId.title), config prefixes (hub.*) and REST paths keep the upstreamhubname. - Keycloak: the login theme is
keycloak/themes/kattaand the realm definition inbackend/src/main/resources/cryptomator-realm.jsonusesloginTheme: katta,displayName: Kattaand/logo.png. Katta also adds clients and mappers to that realm (token exchange forcryptomatorvaults), so merge conflicts in the realm JSON need manual care. - External endpoints: the update check calls
api.katta.cloudwithKatta-Versionheaders (frontend/src/common/updatecheck.ts), and desktop download URLs come fromhub.download-url.*inapplication.properties. Katta documentation lives atdocs.katta.cloud; in-app help links for upstream features still point todocs.cryptomator.orgwhere no Katta page exists.
- Images are published as
ghcr.io/shift7-ch/katta-server,ghcr.io/shift7-ch/keycloakand the chart asghcr.io/shift7-ch/charts/katta-server. Upstream'sghcr.io/cryptomator/hubandghcr.io/cryptomator/keycloakmust not leak into Katta-owned files: checkapplication.properties(dev services),chart/values.yamland the workflows in.github/workflows/after a merge. Upstream'sdeploy/directory is the exception and keeps upstream images. - The application version in
backend/pom.xmlandfrontend/package.jsoncurrently tracks upstream's version; the chart has its own version inchart/Chart.yaml. CHANGELOG.mdis upstream's changelog and is merged as-is; chart changes are recorded inchart/CHANGELOG.md.- The workflows in
.github/workflows/are Katta's own (build, tag, keycloak image, helm chart). Resolve conflicts there in favor of the Katta version and port upstream changes over deliberately.
Both projects share the same Flyway migration directory, backend/src/main/resources/org/cryptomator/hub/flyway, so the version numbers of both projects must interleave without collisions.
- Upstream migrations use plain integer versions:
V30__…,V31__…,V32__…. Katta never adds, renames, or edits a plain integer migration. - Downstream (Katta-specific) migrations use a fractional version
V<base>.<nn>__<Description>.sql, where<base>is the latest upstream migration present in the repository at the time the downstream migration is written, and<nn>is a two-digit counter starting at01. Example:V31.01__StorageProfile.sqlwas written on top of upstreamV31and is followed byV31.02__…until upstreamV32arrives. - Flyway compares versions numerically, part by part, so the order is
V31<V31.01<V31.02< … <V31.10<V32<V32.01. The leading zero is cosmetic:31.01and31.1are the same version to Flyway. Always use two digits to avoid an accidental duplicate. Versions may only contain digits and dots, so a marker likeV31.katta.01is rejected by Flyway; the fractional part is the only way to tell downstream migrations apart. - Test data lives in
backend/src/test/resources/…/V9999__Test_Data.sqland must stay above every real migration.
When developing downstream:
- Pick
<base>= the highest plain integer migration currently in the directory and<nn>= the next free counter under that base. - Only depend on DDL from migrations that sort before yours. Never modify a migration, upstream or downstream, that has already been applied to a production database; add a new one instead.
- Renaming or deleting a migration is only acceptable while it has been applied to test systems exclusively. Flyway's validation then fails on those systems ("Detected applied migration not resolved locally"), so wipe their databases before starting the server again. Locally this means removing the reused Testcontainers Postgres container and running
mvn clean, becausetarget/classeskeeps a copy of the old file and Flyway would still resolve it.
When merging from upstream:
- New upstream migrations (
V32__…) sort after all existingV31.xxdownstream migrations and are applied in that order on existing installations. Out-of-order migration is not enabled, so a migration that sorts below the database's current version is never applied and makes startup fail validation. This is exactly what happens if a downstream migration carries a version above upstream's (e.g.V101with upstream atV31): onceV101is applied, a mergedV31is stuck behind it. - Review each incoming upstream migration against the downstream ones: upstream may rename or drop tables and columns that downstream migrations or entities depend on, or may add objects with the same name. Resolve conflicts with a new downstream migration
V<new base>.01__…that runs after the upstream change, never by editing the upstream file. - Check that downstream JPA entities and Panache queries still match the merged schema, then run the backend integration tests, which migrate a fresh database from
V1throughV9999.
git fetch upstream && git merge upstream/developon a feature branch, resolve conflicts. In files with extension markers, keep the marked blocks; in Katta-owned files (workflows, chart,kattapackages,katta/components) keep the Katta side.- Search the merged tree for upstream brand leftovers:
logo.svg,CRYPTOMATOR HUB,Cryptomator Hub,ghcr.io/cryptomatoroutsidedeploy/, andHubin the i18n files. - Check new or changed upstream migrations against the rules above, then renumber nothing that is already deployed.
- Re-apply Katta behavior that upstream removed or restructured. Upstream may delete a feature or a settings section that Katta still uses; a clean merge of such a deletion silently breaks the Katta UI (e.g. a form whose initialization was removed).
- Build and test all modules:
pnpm buildandpnpm testinfrontend/,./mvnw verifyinbackend/(needs a container runtime for Postgres, Keycloak and MinIO), the Maven build inkeycloak/, andhelm lint chart/. - Merge-only commits should not mix in unrelated refactorings; downstream adjustments of newly merged upstream code belong in follow-up commits so the next merge can tell them apart.