The short version

OBDX's REST layer does not care which client calls it, so a Flutter app can replace Oracle's shipped servicing application. The business logic, the second-factor policy, the timers and the device-count settings all stay on the server and you inherit them unchanged. What you rebuild is the device-trust layer that lives inside Oracle's app bundle: the install-time device identifier, push token registration, certificate pinning, alternate login and the accept-or-reject screen behind push 2FA. That is the real scope, it is security-critical, and it is why this is an integration project rather than a UI port.

There is a question that comes up early in every OBDX mobile conversation and rarely gets a straight answer: can we just build our own app? The answer is yes, and it is less exotic than it sounds — but the reason it is not simply a design exercise has nothing to do with the screens.

We build custom Flutter clients against OBDX APIs, so read this knowing which side it is written from. It is also why the article exists: the thing that surprises people is not what the work involves, it is which half of it involves work.

The API layer genuinely does not care

Oracle ships a native iOS and Android servicing application — its own documentation calls it "the main application for mobile banking" — and that app is built against the same REST surface everything else uses. We have described how the tiers fit together elsewhere: a REST façade in front of a service tier, assemblers, and adapters down to the host. None of that is client-specific.

So the entire substance of a banking app — accounts, transfers, payees, limits, entitlements, approval workflows, the lot — is available to any client that can hold a session and make an HTTPS call. A Flutter client is not working around OBDX. It is using the layer OBDX exposes for exactly this purpose.

What is worth understanding is that the policy stays server-side too, and this is the part that reassures security teams once they see it. The second-factor rules, the expiry windows, the number of devices a user may enrol — those are configuration and database values on the server, not decisions the app makes. A custom client cannot weaken them by accident, because it was never holding them.

THE LINE RUNS THROUGH THE APP, NOT THE API SERVER SIDE you inherit it unchanged the 2FA business policy OTP expiry, held in a config table ALLOWED_DEVICE_COUNT, 1 to 100 ALLOWED_PUSH_DEVICE_COUNT limits, entitlements, approvals passkey relying party and AASA IN THE SHIPPED APP you rebuild it the install-time device identifier push token registration certificate pinning alternate login: PIN, biometrics the accept / reject push screen force update, deep links, widgets EVERY ITEM ON THE RIGHT IS SECURITY-CRITICAL AND NONE OF IT IS A SCREEN WHICH IS WHY THIS IS SCOPED AS INTEGRATION, NOT AS DESIGN
Split derived from Oracle's OBDX servicing application documentation for release 25.1.

Device registration is an identity primitive

This is the one that catches teams out, because the name makes it sound like a convenience feature. It is not. In OBDX, device registration is what makes alternate login possible — the PIN, pattern or biometric path that users actually use every day after the first sign-in.

The mechanism matters. Apple does not permit an app to use a device UUID, so Oracle's documentation describes the device being identified by a unique ID generated when the application is installed — and states plainly that a new device ID is generated after reinstall, or after alternate login is de-registered.

Read that as a product requirement rather than an implementation note. A reinstall is a new device. Your user has not changed, their phone has not changed, but their enrolment is gone and they are back to full credentials. Every custom client needs a deliberate answer for that moment, and "the user will work it out" is not one.

Enrolment breadth is a bank decision held on the server: Oracle documents ALLOWED_DEVICE_COUNT as settable between 1 and 100, with a separate ALLOWED_PUSH_DEVICE_COUNT, and notes that in the documented version only one device may be registered for push. Where a single device is allowed, registering a second removes the earlier registrations — after a prompt warning the user that is about to happen.

So a custom client inherits the rule and owns the conversation. The server will enforce the count. Explaining to someone that signing in on their new phone will sign out their old one is your screen to design, and getting it wrong generates support calls rather than security incidents — which is worse in volume terms, not better.

Push 2FA is timed in three places

Push-based second factor is the feature most worth understanding before you scope, because it spans both halves of the split.

The flow itself is server-driven. A user initiates a transaction, a push notification arrives on the registered device, and they accept or reject from the notification; the transaction proceeds on that answer. The precondition is unforgiving and entirely client-side: it works only if the user permitted notifications when the app was first installed and first signed in. A user who declined that prompt receives nothing, which makes the permission request a security-relevant moment rather than an onboarding nicety.

Then there are the timers, and there are three of them:

  • A countdown shown in the UI, which in the base code sits in the push-out-of-band hook and is expressed in minutes — five, by default.
  • An OTP expiry held server-side in the digx_fw_config_ALL_b configuration table.
  • A business policy validating the generated 2FA token, documented at ten minutes and overridable by the bank with its own policy.

Oracle's own guidance is that the UI value must not exceed the business policy or the OTP expiry. That constraint is the interesting part for a custom client: you are reimplementing the display of a countdown whose authority lives in two other places you do not control from the app. Hard-code five minutes in Flutter, let a bank quietly change its policy, and you have built a client that tells users their approval window is open after the server has closed it.

Read the timer from configuration. It is a small decision that ages well.

Pinning becomes yours, including the rotation

In Oracle's workspace, certificate pinning is configuration: a pinned certificate name set in the application property list, a pinned URL to verify against, and — the detail that matters — separate slots for current and replacement certificates so a new one can ship before the old expires. Pinning is off by default, for development convenience, and documented as recommended for production.

A Flutter client implements all of this itself. Pinning is the easy half; teams usually get that right. The rotation is what gets missed, and it fails in the worst possible shape: silently, on a date nobody diarised, to every user at once, with the fix requiring an app store release that takes days you do not have. Build the dual-slot behaviour in the first release even though you will not use it for a year.

Passkeys are an either-or

Worth knowing before it is promised to a steering committee: Oracle's documentation states that only one of the two login types can exist in the application — passkey, or alternate login by PIN, pattern, Face ID or touch. Not both.

The server side of passkeys is configuration you inherit: a relying party setting, an association file served from the bank's host under the well-known path, and the application identifier properties behind it. The client side is yours. And there is an operational detail with a long fuse — Apple fetches that association file on its own schedule, documented as after five days, which means passkey enablement is not a change you validate on the afternoon you deploy it.

So when is this the right call?

Not for cost. A custom client is more work than configuring the shipped one in the first release, and any estimate suggesting otherwise has priced the screens and skipped the right-hand column of that diagram.

It is the right call when you need UI control the servicing application will not give you, when the bank wants one codebase across banking and non-banking products, when the release cadence has to be independent of Oracle's, or when the app must carry a design system that exists elsewhere in the organisation. Those are product arguments. They are good ones, and they are the honest basis for the decision — which is also why we scope the integration before anyone designs a screen.

The related decision, if you are weighing this, is whether the UI is served remotely or built into the binary at all. We have set out why remote versus local UI is not a style choice separately, and it is worth settling first: it changes what a custom client even means.

Questions we get asked

Can you build an OBDX mobile app in Flutter?

Yes. Oracle ships a native iOS and Android servicing application, but OBDX's business functionality is exposed through a REST layer that is not tied to that client. A Flutter app can consume those same APIs. There is no Oracle Flutter SDK, so this is custom integration work rather than a supported toolkit path, and the device-level features in Oracle's app bundle have to be rebuilt.

What do you lose by not using Oracle's shipped mobile app?

Chiefly the device-trust layer and the platform plumbing. Oracle's workspace handles the install-time device identifier, push token registration, certificate pinning, alternate login with PIN or biometrics, the accept-or-reject screen for push-based second factor, force update, deep links and home screen widgets. The server-side policy behind all of it stays available to any client, but the client-side half is yours to build.

Does OBDX device registration survive a reinstall?

No. Oracle's documentation states that because Apple does not permit use of a device UUID, the device is identified by a unique ID generated when the application is installed, and a new device ID is generated after reinstall or after alternate login is de-registered. Any custom client has to treat reinstall as a fresh device and re-enrol the user accordingly.

How does push-based 2FA work in OBDX?

When a user initiates a transaction, a push notification goes to the registered device and the user accepts or rejects it from the notification. The transaction proceeds on that answer. It only works if the user permitted notifications at first install and first login. Three timers govern it: a UI countdown set in the push-out-of-band hook, an OTP expiry held in the digx_fw_config_ALL_b table, and a business policy validating the 2FA token.

Does certificate pinning come for free in a custom client?

No. In Oracle's app it is configuration — pinned certificate names and URLs set in the application property list, with separate slots for current and replacement certificates so they can be rotated before expiry. Pinning is off by default for development. In a custom client you implement pinning yourself, and you need the rotation story from day one, because a pinned certificate reaching expiry without a shipped replacement locks every user out.

Is a custom Flutter client cheaper than customising Oracle's app?

Not in the first release, and anyone saying otherwise is pricing the screens rather than the device-trust layer. It pays off where you need UI control the shipped app will not give you, a shared codebase with non-banking products, or a release cadence independent of Oracle's. Those are product arguments rather than cost arguments, and they are the right basis on which to decide.

How many devices can a user register in OBDX?

It is configurable by the bank. Oracle's documentation describes ALLOWED_DEVICE_COUNT as settable between 1 and 100 for alternate login, and a separate ALLOWED_PUSH_DEVICE_COUNT for push. In the documented version only one device is permitted for push. When a single device is allowed and a user registers another, the previous registrations are removed after a confirmation prompt.

Related service OBDX mobile app development Custom Flutter, React Native and native on OBDX

If you are weighing a custom client against the shipped application, the scoping conversation worth having first is about the right-hand column — device trust, pinning and the second-factor path. That is where OBDX mobile projects are won or lost, and it is cheaper to settle it in a week than to discover it in UAT.