The shipping report 🚢

We missed a couple of these. Sorry about that, we've been so busy! Here's what's new on the product side.

Login with Teller

Login with Teller is how users safely authorise your apps access to their bank accounts. It's a huge step change in every dimension: safety, UX, speed, and developer experience.

We also announced that we're making our APIs free in production.

You can now go into production completely self-service. This is a big one, so we gave it its own post.

New bank alert 🚨

We now have full support for HSBC, Tesco Bank, and Metro Bank. You can enroll your HSBC, Tesco Bank, and Metro Bank accounts, to view account information, balance, recent transactions.

You can see standing orders and payees for Tesco Bank too. We'll be adding those to Metro Bank in a future release. Direct Debits and standing orders are currently not made available by HSBC via their mobile banking interface.

This brings us up to 11 supported UK banks

Nationwide update: Direct Debits, payees, and standing orders

We've expanded our Nationwide integration to pull down transactions as far back as we can, and added Direct Debits, standing orders, and payees to the API too.

International telephone number support

This was a silly one, but we used to require a UK mobile number to sign up. As an API provider for UK banks we thought this was a reasonable assumption to make, but it turned out a lot of people outside the UK are interested in Teller too, so we removed this requirement.

That's all folks. See you next time.

Login with Teller

Big news today folks. Today we're launching Login with Teller, the safest way for users to connect their bank accounts with the financial apps and services you've been building during our developer beta.

Also, today we're happy to announce that we're making our APIs completely free of charge*.

Going from the first time opening a Teller powered app to actually using the app with live data from your accounts takes less than 25 seconds.

Login with Teller makes some essential and fundamental improvements to how users give consent to financial apps requesting access to their bank accounts. Teller places user needs first, making it an easier decision for users to trust your app.

Users can choose to hide entire accounts from an app before authorizing.

Login with Teller uses TAuth, today we're open-sourcing tauth_proxy to help you develop more secure financial apps.

That's all for now folks. Create an application, have a read of the TAuth docs, and let us know what you build. 😊

* APIs are provided free of charge subject to fair use. Support and SLAs not included. Contact for options.

The shipping report 🚢

Here is what we shipped in August 2017


Teller's first hire the awesome (Dan Palmer) added support for enrolling TSB accounts and viewing recent transactions. Direct Debits, payees, and standing orders coming soon.


We added payes, standing orders, and transactions to the Santander integration. Direct Debits coming soon.

Security enhancements for user accounts

We shipped so much stuff here we gave it its own blog post.

That's it until next time. See you next month. 👋

Improving user account security

We've recently shipped a number of security improvements for how users sign in to Teller: TOTP as a 2nd factor, an account recovery flow, an SMS OTP roaming check, and other authentication and sign-up changes.

TOTP 2nd factor

You can now use a TOTP app, e.g. Google Authenticator to generate time-based one-time passwords as your 2nd factor. To enable TOTP on your account, install a TOTP app on your phone, go to the user settings page, select the TOTP option, scan the QR code into your TOTP app, and enter your password to confirm the change.

Back in the earliest days of our private beta Teller initially mandated TOTP as the 2nd factor but it didn't test well with users. You won't be surprised by this if you've ever been the owner of a GitHub Org and had to enforce a 2FA policy. Teller moved to OTP via SMS so that we didn't lose a bunch of users while also providing some kind of 2nd factor.

Despite its shortcomings SMS OTP provided good UX and an acceptable level of risk considering the sophistication of our earliest users (software developers), and that it wasn't yet possible to reset passwords or to initiate payments. As Teller continues to develop these assumptions no longer hold and given that NIST has since deprecated authentication via SMS we have brought back TOTP.

We strongly encourage you to switch your 2nd factor to TOTP and away from SMS OTP.

SMS OTP roaming check

One of the drawbacks of using SMS as a 2nd factor is that it means you're effectively delegating your security policy to a 3rd party that you don't control and can't ensure performs competently. A major problem with SMS is that attackers have gained access to the signalling network that network operators use to route calls and messages to you no matter where you are, even if you're on the other side of the world. This network, known as SS7 was designed a very long time ago in a time where the threat model was very different, consequently anyone with access to the network is de facto trusted. Once an attacker has access to SS7 they are able to fool your home network into thinking you're roaming on their phoney network. Your home network will now helpfully forward all of your calls and SMS to the attacker.

We now check if your mobile number is roaming before sending one-time passwords via SMS. We will no longer send one-time passwords via SMS while your number is roaming on a foreign network.

This does not completely eliminate the problems with SMS OTP, they're still vulnerable to an attacker who successfully manages to impersonate you to your network, convince them you've lost your SIM card and have them transfer your number to an attacker controlled SIM card. They're also still vulnerable to any malware on the device that could intercept your SMS (although if your device is compromised, all bets are off anyway).

Again we strongly encourage you to switch your 2nd factor to TOTP and away from SMS OTP.

Account recovery

You can now reset the password on your Teller account by telling us the telephone number registered with the account, whether or not you have any bank accounts connected to it, and if so the account number, sort code and ledger balance of one of the connected accounts. You can find out the ledger balance of a connected bank account by logging on to your bank's online banking, using their mobile banking app, or by doing it the old fashioned way and calling them or visiting a branch. By being able to tell us your bank account details and a current ledger balance you demonstrate sufficient control of a connected bank account for us to let you reset your password.

Resetting your password does not log you in or reset the 2nd factor. If you've forgotten your password and lost control of your 2nd factor contact support and we will try to help as best we can.

Changes to login and signup

When we originally built the user authentication flow, we wanted it to be as frictionless as possible. The user would enter their telephone number, Teller then sent the user a OTP via SMS, the user would enter the OTP, and if there was an existing account for that number Teller would ask you for your password. If there wasn't an account we would ask you to choose a password and automatically create an account and log you in.

The problems with this approach is that we would send an SMS before the user had authenticated meaning we had essentially published an endpoint that allowed an attacker in theory to spam anyone with messages from Teller, and less importantly cause Teller to incur unlimited expense from this unauthorised usage. This never happened but we wanted to change it before it did. The easiest way to solve the issue would be to require valid password before sending the OTP SMS, unfortunately we'd just be replacing one problem with another, i.e. an easy way for attackers to quickly enumerate whether a given phone number was associated with a Teller account. We decided to solve this issue by splitting up account creation and user login into separate features.

As always we welcome your comments and questions. Please write to us at

The API for your bank account is here

Hey folks,

How many times have you thought to yourself “Damn, I really wish my bank account had an API”? I bet the answer is a lot. Well, today is the last day you will ever think that again because we are pleased to announce that the Teller API beta program is now open to the public.

Starting today, you can create a developer account, connect your bank, and start making live API calls into your bank accounts in less than 5 minutes.

Live data, fast

If you’ve ever integrated with an account aggregator that works by “screen-scraping” you will appreciate what a leap forward Teller represents. Never again will you deal with day-old stale data or wait tens of seconds while it is refreshed for slightly less stale data.

Every Teller API call hits your bank to return current live data reflecting the current state of your account. Not only does Teller return live data, it does so extremely quickly, in most cases under a second.

Do you have accounts at multiple banks? No problem, we will communicate with each bank concurrently and return normalised JSON to you in the same time it takes to fetch data from a single bank.

A step-change in user experience

Another big problem with the latency “screen-scraping” suffers from is that interactivity is made very painful, for example when onboarding a user to your product using a screen-scraper to fetch data it can be dozens of seconds before the user gets any feedback.

Consider this side-by-side comparison of the Teller onboarding flow and the account onboarding flow of a typical Fintech app that uses screen-scraping.

Look how long it takes for a screen-scraper to fail when supplied with bogus data, while Teller comes back instaneously with an error message. Imagine this is your user making a typo while entering their information. You can guarantee users will delete your app in frustration if this is their first experience.

A quantum-leap in capability

Although we are not launching this functionality today, Teller is the first banking API available to the public that is capable of moving money and managing your account. Transfer money between accounts, make external payments using Faster Payments, and manage your payees, standing orders, and Direct Debits all through the Teller API. For the first time in history it is possible for a developer to build a full replacement the bank’s own first party app. If you have the product chops you might now be thinking about the possibility of disintermediating banks altogether.

Stay tuned for more informations on these APIs in the coming weeks.

No shenanigans

The preferred business model of the incumbent screen-scrapers seems to be:

We do not believe in that. We won’t charge you a setup fee, make you jump on a call or watch a webinar to get started. You can spend as little as you like, and you can leave us at any time. We want to provide you with such a great product experience that you will never leave and will want to tell everyone about it.

We realise that our revenue will most likely be a very long tail with a small number of customers bringing in most of the cash. So we want to cast the net as far as possible to increase the chances of finding those customers from day 0. This is why Teller is free for apps with up to 100 users. We want you to hack out that idea you’ve been kicking around for the past 6 months. We want you to do it now and we want you to ship. Teller is 100% aligned with you and your users.

Your success is our success.

Teller is available today for Santander UK, Barclays, Natwest, Nationwide, RBS, Isle of Man Bank, and Ulster Bank.

Create a free developer account today.

We can’t wait to see what you build.

Stevie Graham (@stevegraham)


Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're fixing it

This week we released our authorisation flow making it possible for you to go from building apps that talk to your bank account, to building apps that can talk to any bank account. This is huge. Check out this SMS bot (how on trend) I hacked up yesterday morning. (and don't forget to join the beta wait list).

Getting to this point took longer than we expected. This is because there wasn't a good story for delegating authorisation for sensitive APIs. The most popular choice, OAuth 2.0 - which has been chosen by the Open Banking Working Group, BBVA, RBS, and Mondo - is also amongst the worst from a security perspective.

Teller provides an API for your bank account. The EU is forcing all European banks to expose account APIs with PSD II by end of 2017. These banks are disconcertingly converging around OAuth 2.0* without fully considering the impact on their customers, and something needs to be done before it's too late.

* One notable exception is the Open Bank Project. It is sticking with OAuth 1.0a precisely because OAuth 1.0a doesn't share the same security issues as OAuth 2.0.


One of the biggest problems with OAuth 2.0 is that it delegates all security concerns to SSL. This is a bad because only the client authenticates the server, the server doesn't authenticate the client. The client does this using the provided SSL certificate. This means the server has no way of knowing who is actually sending the request. It's lacking Is it a bona fide user, or is it an attacker tampering with the request?

When an attacker is able to insinuate themselves between a legitimate user and the server, it's called a man-in-the-middle (MITM) attack. It looks like this:

You're probably thinking "hang on, isn't this the point of SSL?" Yes it is, but there are a number of ways to present a bogus certificate and a client accept it. The most realistic threat is the client developer not properly verifying the server certificate, i.e. checking if the certificate was signed by a trusted certificate authority?. This check is called SSL peer verification and it can be disabled in special situations.

Unfortunately a large number of developers think that disabling SSL peer verification is the correct fix to an SSL path validation error. There are many more that will offer the same advice with the caveat that it introduces a security issue You cannot guarantee that all readers will consider this advice. As an API provider with a duty of care to our users we can't simply hope developers on our platform don't disable SSL peer verification.

Bearer tokens

A user can authorise an application to access its account. This application obtains a bearer token from the authorisation server.

As the name suggests if you have possession of the bearer token then you are considered to be the user. There is no cryptographic proof that the requesting client is the intended developer and not an attacker. If an attacker is able to successfully MITM a client it could have catastrophic implications for the user, e.g. an empty bank account, loans opened in their name, etc. OAuth 2.0 is not fit for purpose when applied to banking, let alone banking APIs. Banks have no way to prove that an API transaction is from the user in question, exposing them to unlimited liability.

For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens are a Terrible Idea and OAuth 2.0 and the Road to Hell by Eran Hammer the original primary author of OAuth 2.0 who formally removed his name from the standard, calling it "the biggest professional disappointment of [his] career."

Finding something better

Sitting down to design the solution to this problem I had two high-level goals:

From a security perspective I wanted:

Non-repudiation is a de facto requirement of PSD II. If a bank can't prove an account owner authorised a transaction, they're liable for any losses incurred by the user.)

There are solutions to the bearer token problem like JWT tokens (RFC7523) but in most cases these rely on a shared secret which is used to computed a HMAC-based signature. Shared secrets mean no non-repudiation. Public key cryptography can be used with JWT tokens but they don't solve the problem of how the client will generate key pairs, demonstrate proof of possession of the private key, and enrol the public key with the API. Most importantly using JWT tokens make it basically impossible for you to experiment with an API using cURL. A major impediment to developer experience.

In an ideal world we'd have cryptographic proof of the client's identity without it having to leak through the application level (and stop us cURLing the API!). As I thought about it it became the clear the answer was hiding in plain sight: SSL client certificates.

Client SSL Authentication

A SSL handshake involving client certificates contains an extra message at the end of the handshake, the CertificateVerify message.

  Client                            Server

  ClientHello        -------->
                     <--------      ServerHelloDone
  Finished           -------->
                     <--------             Finished
  Application Data   <------->     Application Data

         Fig. 1 - Message flow for a full handshake

The client collects all the handshake messages and signs them with it's private key and sends the result to the server. The server then verifies the signature using the public key of the client certificate. If the signature can be verified with the public key, the server knows the client is in possession of the private key, and is therefore a bona fide user.

Let's look at this in the context of our original attack:

Introducing TAuth

TAuth is Client SSL Authentication + User Tokens + Great Tooling.

Client SSL authentication is often overlooked because of the poor UX of using client certificates in the browser and that generating certificates is a painful multistep process involving arcane OpenSSL CLI incantations. However as we're talking about API clients the browser UX point is irrelevant. As far as certificate generation goes, we can write better tools. These days it's possible to generate a key pair, a PKCS#10 certificate request, and sign it all in the browser. Thanks to WebCrypto the whole process is reduced to one click.

This is how Teller does it:

A private key and a SSL certificate signed by Teller generated in one click.

And this is what a request looks like with client certificates:

Let's recap what we've achieved here:

Token security

Notice in the above example. The Teller API accepts connections from clients without a client certificate. We do this because we provide developers with read-only personal access tokens for their own accounts if they want to quickly hack something up and not bother with provisioning certs. Now notice how the API does not accept the token presented, but accepts it when used with the client SSL certificate. TAuth bearer tokens are bound on the server side to a private key through an application. This means they are useless without the private key (which only the developer ever has) and therefore not sensitive. As matter of fact, here is one for my bank account:

Ruby client

You'll need the private key it's bound to for it to be of any use, and that has never left my laptop.

TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the concept of time-limited tokens. Large internet companies found it useful for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks are developers have to pay the complexity cost of refreshing tokens and most importantly tokens cannot be revoked, they're good until they expire. For bank account APIs this is an undesirable property, a token should be void as soon as the account owner wishes. TAuth checks the token revocation status at each request.

Given that we have no need for self-encoded tokens and that tokens are useless to anyone without the private key, we can consider them public and directly return them in the callback further simplifying things for the developer compared to OAuth without compromising the user's security.

Bonus: DDOS mitigation

TAuth can help mitigate layer 7 based DDOS attacks too. If the client does not present a valid client certificate the server can just choose to bounce the connection.


OAuth 2.0 is simply not fit for use with sensitive APIs and all the pieces needed to build something that is exist today. Aside from unbound bearer tokens, OAuth is too open-ended and complicated to get right for most developers. It's so bad it even has it's own threat model as a separate RFC to offer mitigations for the endless problems that can happen.

TAuth stands for Trusted Authentication, and it provides the best security for users while maintaining the highest possible quality developer experience. Less can go wrong when everything is simpler. If your bank has OAuth 2.0 in production you must ask yourself, do they really know what they're doing?

TAuth is available in production today for our existing beta users and we've already begun the work to make it an open standard we hope the industry adopts. If you're at a bank and want to offer your customers the security they deserve email me - sg at

Create a free developer account at