Updates to App Hub requirements: use Routes when connecting to external services

Dear DHIS2 Community,

To ensure high quality of our apps on the App Hub, now that Routes are available in all supported DHIS2 versions (v40+ at the time of this post), we are making the following changes to the App Hub Submission Guidelines.

App maintainers are strongly encouraged to move away from browser-based credential handling and instead use DHIS2 Routes, which can be managed through the Route Manager App or via the DHIS2 Routes API.
To support this transition, we have published a short migration guide here.

Please migrate by mid-June 2026, ahead of the DHIS2 Annual Conference (15-18 June).
After this date, we will review existing apps on the App Hub and unlist any that don’t yet follow the new security guidelines.

If your app currently stores or fetches third-party credentials in client-side code or in the data store for browser use, please prioritize migrating to route-based communication.

If you have any questions, please feel free to reach out to us!

Best regards,
Team Extensibility

3 Likes

Thank so nuch Johan

1 Like

Thank you @JohanHole for sharing this update and for the work that has gone into improving the security posture of apps on the App Hub. The migration guide is also very helpful for developers who are evaluating how best to adapt their apps to the newer Routes functionality.

I strongly agree with the broader goal of reducing insecure patterns in apps, particularly the practice of embedding third-party credentials directly in client-side source code (regardless of whether they are in clear or encoded text). There is clear agreement I think across the board that this is not great security practice. That said, I would like to raise a few questions about the current guidance to avoid the user-data store for handling tokens or other secrets.

In many implementations, it is possible for an app to store a user-scoped secret (for example, an API token to an external service) in the user data store in encrypted form, and then retrieve and use that token only when the authenticated user makes a request through the app. In this pattern, the token is effectively bound to the individual user and is not shared across users. In theory, this means the upstream service can retain visibility into which specific user is making requests.

By contrast, when using Routes (at least as I understand how they function), the credentials configured for the route are defined centrally by an administrator and then used for all requests that pass through that route. While this has the advantage that the credentials are never exposed to the browser, it also means that the upstream service typically sees a single identity rather than the individual user who initiated the request. This could possibly be mitigated by sending the actual user as a header or request parameter of course (but of course could be trivially spoofed).

For integrations where the external service needs user-level attribution, auditing, or perhaps are rate-limited by user, this difference can be significant. In those cases, a user-scoped token model may still be desirable from an architectural perspective.

Because of this, I wonder whether the recommendation might benefit from a bit more nuance?

  • Hard-coded credentials embedded in client-side code (which should clearly be avoided), and
  • User-scoped secrets stored securely and retrieved at runtime , which may support integrations that require per-user identity at the upstream service.
  • Route based API requests where the credentials are never visible to the browser, but where user-level attribution to the request may not be resolvable by authentication details.

Routes provide a very valuable capability, particularly for service-to-service integrations and for protecting shared credentials. At the same time, there may still be legitimate use cases where user-scoped tokens are preferable from an integration or auditing standpoint.

One additional point worth discussing is the assumption that any credential visible to the browser is inherently insecure. In practice, the browser already holds authentication details such as session cookies (e.g., JSESSIONID) . These are also present in browser memory during normal operation. As a result, the security model of web applications typically relies on transport security, origin restrictions, and server-side authorization rather than the assumption that credentials never reach the browser at all.

It would be helpful to clarify whether such patterns are considered acceptable under the updated guidelines, or whether the intention is to require all external service communication to go through Routes regardless of the authentication model.

Thanks again for continuing to evolve the App Hub guidelines and for engaging the community in these discussions.

Best regards,
Jason

Thank you for the feedback @jason, all good points.

I agree that the migration guide might come across as fairly narrow in scope. However, some of the concerns you mention are already reflected in the current guidelines (for example that hard-coded credentials in client-side code should be avoided). But I agree, the distinction between what is strictly disallowed versus strongly discouraged could probably be clearer.

I also see the point you raise about the blog post and the current guidelines not aligning 100% on this topic. I’ll bring it up with the team so we can take a closer look as we continue evolving the guidance.

Appreciate you taking the time to share the input.

Best,
Johan

1 Like