How we shield rotki against supply chain attacks

Update: This post was updated after initial publishing to mention our 7-day cooldown period before updating dependencies.

rotki is a local app that helps you to keep track of your crypto activity both as transactions on different chains and on CEXes like Coinbase, Kraken, Binance, etc. This information is quite sensitive and there are reasons to not leak it. It is critical for us that what reaches your computer is exactly what we built. Anything less puts our users at risk.

For this reason, after the recent attacks 1 2 3, we reviewed our dependency supply chain and the measures we’ve had in place since day one. rotki has many moving parts and its architecture spans different stacks and layers: package managers, CI, packaging pipelines, distribution. All of them need to be secure.

There is no magic solution that makes the process 100% secure. But you can make attacks harder, reduce the places where trust is implicit, and make releases easier to verify. This is what we currently do.

Locked dependencies everywhere

The first rule is that builds should not decide dependency versions on their own.

All the ecosystems we use have lockfiles and we treat them as part of the source code. If a dependency changes, the lockfile has to change too and that change has to be reviewed. This gives us a clear place to see what was added, removed, or upgraded.

In practice this means:

  • Frontend: we use pnpm install --frozen-lockfile, so pnpm-lock.yaml must already contain the exact dependency graph.
  • Backend: we use uv sync --locked, so Python dependencies must match what is in uv.lock.
  • Rust service: we use cargo fetch --locked, so Cargo will not resolve any unexpected version.

This is important because package registries are mutable environments. A maintainer account can be compromised, a package can be transferred, or a new version can be published with malicious code. If CI installs “whatever is latest that satisfies the range”, then an attacker only needs to influence dependency resolution once.

With locked installs, CI installs what we reviewed before. If someone wants to update a package, that becomes an explicit code change.

Also for the node ecosystem we use pnpm instead of npm since it offers additional protections and most of the recent attacks haven’t affected pnpm users.

Release builds do not use dependency caches

Our CI for tests and on-demand builds runs entirely on GitHub, and we use caches because they save a lot of time. We make several PRs per day and waiting for every dependency to be downloaded from scratch on every branch would be painful.

Releases are different. They happen less often and they are what the user will receive. For releases we prefer the slower and cleaner path.

For release workflows we disable package manager caches:

# rotki_release.yaml
enable-cache: false          # uv
package-manager-cache: false # pnpm

The reason is cache poisoning. If a malicious dependency, binary, or intermediate artifact lands in a cache, the release job could reuse it without ever pulling the legitimate version. That kind of failure is hard to notice because everything can still look reproducible from the outside.

So for releases we build from scratch, using the locked dependency versions and fresh downloads. It costs more CI time, but this is one of those cases where speed is not the priority.

GitHub Actions are pinned to commit hashes

CI configuration is code too. In many projects this part is overlooked, but the actions used in GitHub workflows have a lot of power. They can read the repository, access secrets depending on the job, upload artifacts, and influence what gets released.

For that reason we pin GitHub Actions to full commit SHAs instead of tags:

uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2

Using tags like @v6 or @v6.0.2 is more convenient than pointing to commits but tags are also more dangerous. If a tag is moved, or if an upstream project is compromised, the same workflow file can suddenly execute different code. A commit hash is immutable and explicit: it points to exactly which code we are trusting.

Build provenance attestations

Users should be able to ask: “Was this binary built by rotki, from the rotki source code, in the expected CI environment?”

To help answer that, we generate build provenance attestations for release artifacts using actions/attest-build-provenance. This attaches verifiable metadata to the artifact.

The attestation links the binary to the workflow that produced it and to the source revision used for the build. This is useful because it narrows the trust problem. Instead of only trusting a file that appeared on a release page, users and downstream distributors can verify where it came from.

This matters especially for desktop applications like rotki since people download a binary and run it locally. If an attacker manages to replace an artifact after the build, provenance checks give us and users another way to detect that the file is not the expected output of our release process.

More information is available here

Note: In the case of the Windows version we are forced to sign the binary locally with a YubiKey and reupload it. The Github attestation will fail because of that.

Trusted publishing instead of tokens

Publishing credentials are dangerous. An npm or PyPI token can leak from a developer machine, CI logs, a misconfigured secret, or an old environment nobody remembers. For packages we publish ourselves, we avoid that model completely and use trusted publishing with OpenID Connect (OIDC).

With trusted publishing, the registry does not use a token at all. Instead it verifies that the publishing request comes from the GitHub Actions workflow we configured. The permission is tied to the repository, the workflow, and the release process.

This has two advantages:

  • There is no secret to steal.
  • Publishing is constrained to the CI path we control.

New dependencies go through quarantine

The easiest way to reduce dependency risk is to have fewer dependencies. Of course we cannot write everything ourselves and good libraries save time and prevent bugs. But every new dependency is also new code that runs in our application, new maintainers we trust, new transitive dependencies, and a new update stream to monitor.

So we do not add dependencies casually. Before adopting a new package we look at things like:

  • Who maintains it?
  • Is the project active?
  • Does it have a history of suspicious releases?
  • How many transitive dependencies does it bring?
  • Is the package doing something simple enough that we should implement it ourselves?
  • Is vendoring a small piece of code safer than depending on the whole package?

When a dependency is accepted, it is always added with locked versions. As an extra precaution, we also apply a 7-day cooldown period before updating dependencies to newly released versions, giving the ecosystem time to detect and report suspicious releases. We have to be honest about the fact that maintainers are themselves attack targets and that dependency graphs grow fast.

Closing thoughts

Securing the supply chain for any software is hard and no single measure shields you. It takes several layered steps and even then nothing is perfect. The practices above are some of the most important ones we take to ensure that the software you receive from rotki is exactly what you expect from us.

None of this means we are done. Security work is never finished. But we think this is the right direction: less implicit trust, more reviewable state, and release artifacts that are easier to reason about.

Why we’re changing rotki’s pricing after more than 7 years

rotki has had the same subscription price since our founding at the end of 2017. That’s more than seven years without a single price change, through rising costs, rampant inflation, new integrations, countless DeFi upgrades, and the growth of our small team maintaining an ever-expanding codebase.

During that time, the app evolved massively.

We’ve added support for dozens of new protocols and chains, onchain data decoding, new accounting features, reporting exports, analytics, active management of funds and many improvements to the local app itself: all while staying fully privacy-preserving, open source, and independent. But our pricing never moved. That’s not sustainable anymore.

We don’t sell user data. We don’t take a cut from transactions. We don’t inject analytics or tracking. Our entire income comes from people who choose to support us directly. That’s what keeps rotki independent and what makes it very different from most modern “cloud apps.”

To keep developing at the quality and pace users expect, we’re introducing a new tiered subscription system.

The new structure

  • Free - stays exactly as it is today. All core local functionality remains free forever.
  • Basic - is now priced at €25/month (VAT included) and replaces today’s “Premium” tier.
  • Advanced - for power users with more heavy needs. This tier raises all limits(devices, DB size etc.) and is tailored for people managing more diverse portfolios.
  • Custom - For businesses, family offices, high net worth individuals whose needs go beyond the advanced tier. Includes tailored limits, dedicated support, and more.

All current Premium subscribers will automatically move to the Basic tier starting from November 10th, 2025 and onwards. As part of this update, we’re also simplifying subscription periods. All existing plans that renew every 3 or 6 months will automatically switch to monthly billing at the Basic tier price (€25/month, VAT included) starting November 10th, 2025.

If you prefer not to continue, you can cancel your subscription before that date. Otherwise, no action is needed, your next billing cycle will switch to the new plan and price.

Why we made this change

rotki was built with one goal: to give users full control of their financial data without having to share it with third parties or store it in other people’s servers. That goal doesn’t change but building and maintaining such software isn’t cheap. Far from it.

Over the years:

  • Admin expenses, inflation, devops has all become much more expensive.
  • Our workload grew as DeFi exploded: hundreds of new chains, thousands of protocols, token standards, and quirks to handle. We are downstream of all these and have to adjust things continuously and respond to dev changes made many times by amateur teams.
  • We’ve been running on a shoestring budget for years, kept alive largely by passion and community goodwill.

Until now, rotki’s revenue has mostly come from grants for integrations, followed by donations through campaigns like Gitcoin and Giveth, and lastly from premium subscriptions. The problem is that both grants and donations are unpredictable. They depend on third parties and changing funding cycles. To build rotki sustainably and plan long-term, we need a more stable foundation, and that means making user-supported revenue the main driver of our growth. rotki is not a mass-market app, it’s a precision tool for people who care about control and privacy.

We price accordingly, to build something that lasts.

This update simply aligns pricing with the reality of what it takes to keep rotki alive, reliable, and improving.

We know price increases are never pleasant, but this is what allows us to:

  • Continue offering an OSS, self-hosted privacy-preserving app.
  • Keep all data processing on your machine: not ours.
  • Fund ongoing maintenance and new feature development without having to resort to shady business practices and exploit the data of our users.
  • Add extra tools, such as indexers for our premium users which will speed things up and make data retrieval for prices and events faster. A commonly mentioned pain point for rotki as it currently stands

Our commitment to openness, privacy, and user alignment stays absolute.

If you’ve been supporting us, thank you. You are literally the reason rotki exists. If you haven’t yet, or you paused your sub, now is a good moment to rejoin and help us keep building independent, self-hosted software in a world moving toward the cloud.

The Power of Open Source: Why rotki’s Transparency Is Essential for Trust

In an era where data privacy and security are at the forefront of our digital lives, transparency has become a key factor in building trust. For individuals managing cryptocurrency portfolios, trust is not just a preference—it’s a necessity. This is where rotki, an open-source portfolio tracking and management tool, sets itself apart from competitors by emphasizing transparency as a core value.

What Does Open Source Mean?

An open-source project makes its source code public so that any person can see it, alter it, or even go so far as to contribute to the codebase. An important part of being open source means allowing others to build their products on top of yours. For more check the OSI definition. In the context of rotki, this means everything in terms of the inner workings of the software being open to anyone who wants to inspect them. This means that users do not have to take the word of the company for anything; they can inspect the code independently or use independent, third-party reviews by security researchers to ensure there are no hidden vulnerabilities or data-handling practices that might compromise their privacy.

Why Transparency is Important in Crypto Portfolio Management

Cryptocurrency was founded on decentralization and user empowerment. Crypto users usually want tools that enable full control over their money and data. Open source allows complete transparency where no decision-making about your security or information will be hidden from you; everything is in the open for you to see and understand. Transparency is of utmost importance in software like rotki for the following reasons:

  1. Trust Through Code Inspection: Because it is open source, everybody has the opportunity to inspect said software for its intended workings without any backdoors or hidden security risks. In this case, users of rotki can verify that their financial data will stay on their device and not be sent to third parties. That alone gives peace of mind to the user as their sensitive information is safe.
  2. No hidden backdoors: Open-source software means removing any threat of hidden backdoors that can leak your data. With closed-sourced software, users are not sure their information will be secure. Even companies that you can trust can fall prey to security breaches. Rotki being open-source by nature makes everything at least visible, and hence there’s little room for doubt about its integrity.
  3. Community Contributions: The success of any open-source project is dependent on community contributions. Bug reporting, active improvement suggestions, and even code contributions mean rotki is constantly improving. This will keep the software updated, secure, and receptive to the users’ needs. The more eyes look at the code, the faster bugs can be found and fixed, hence rotki gets more bullet-proof with time.
  4. Innovation through Transparency: Free and open-source software allows any developer to start working on projects based on code that already exists. Using the case of rotki, for example, people can build new features and even completely new tools on top. That means rotki evolves with the community, updating at every turn based on the input and ideas of its users.
  5. Aligned with Decentralization: Decentralization is central to cryptocurrency, and open-source software aligns with this principle. Rotki’s transparency ensures users aren’t tied to one company. They can access the code, modify it, and develop it independently. This gives users more control and freedom, so they’re not limited by one company’s rules.

Rotki: Example of Open Source Done Right

Rotki goes beyond being a typical portfolio management tool by fully embracing open-source principles to empower its users. Here’s what makes it unique:

  1. Data Privacy: All your financial data remains on your device. Rotki does not store or process your data on its servers, and this promise can be independently verified by taking a look at its source code.
  2. Community-driven: Contributions come in from users all over the world. Be it feature requests, bugs, or even writing code, the community drives how rotki evolves.
  3. Security by Transparency: The basis of security in rotki lies in the very fact that the community can always audit and verify the codebase so no malicious practice goes unnoticed, including data siphoning and unauthorized access.

Try it out here — rotki.com

Key Takeaway

The power of open-source software is in its transparency, and this is invaluable for a crypto portfolio manager like rotki. In an industry built on decentralization and trust, the open-source nature of rotki assures users that their financial data is secure, private, and fully under their control. With the code open to all users, you will have the ability to inspect it, contribute to its improvement, and benefit from the oversight provided by the community at large. With rotki, you will join a community that embodies transparency, innovation, and the user’s empowerment.

If you want more info on rotki:

  • Try out rotki’s latest release
  • Buy premium, unlock all features and support our development.
  • Check out our Github repo and follow us in Twitter.
  • Chat with us and other users of Rotki in Discord