It’s all about the “Auth”
- Planning for test automation in your shiny new API?
- It’s all about the “Auth”
- Do your tests fail the right way?
In the first post in this series I shared my horror in discovering that my process for Authenticating my API tests was broken. Suddenly I had no means to make the API calls required to test that my services were responding as expected. So what exactly do I mean by an Auth service?
The two “Auths”
I have gone to great lengths to build up my super new data service, the best in the world. Now I want to release this service to the world, but of course I also want to get paid. So I need to perform two checks:
- Who are you? (Authentication)
- Are you allowed to use this particular service? (Authorisation)
Authentication
From an automated test perspective this can be the most challenging problem. Some approaches for Authentication:
None
I don’t care who or what you are.
From my perspective:
Unfortunately this is the most common approach on freely available API test training resources and is also commonly used when first developing a new API.
This is unfortunate as it it is usually a tougher problem to solve than actually testing the API endpoints.
Client Authentication
I don’t really care who YOU (the user) are, as long as you are accessing me from an approved client.
Simple bearer token
When you sign up for / renew your contract I give you a fixed token to use. I’m going to trust that you will keep this token secret and only use it for yourself.
From my perspective:
The good news is that this is generally the easiest to set up in your Automated tests. Just add the appropriate Authorization
header and don’t forget to test that a known invalid token returns http status code 403.
User Authentication
Username / password
Now I need to provide you with an account that has both a username and a password that you send to me whenever you want to use my service. (And presumably a means to change at least the password)
From my perspective:
Assuming that they are attached in a header this is easy to Automate, but not a particularly secure approach.
OAuth
An authentication service uses appropriate means to verify that you are who you claim to be and issues a short lived access token that is used for API calls and a longer lived refresh token that can be used to generate a new access token when it expires.
It is up to the Oauth service implementation to decide how to verify the user, from a simple user password login UI to adding reCaptcha, multifactor apps / devices or even biometric scanning.
From my perspective:
At face value, if an Oauth service is genuinely using an effective multi-factor authentication or biometrics process this SHOULD be impossible to automate. That’s really the point of it.
There will have to be compromises between security and how truly you are actually testing the production code.
Alexander Oliveira Dunn: This article..
So…. we just give up even trying to automate API Testing?
No, that is not actually what I am saying, but you do need to have some serious discussions with your developers and security experts on which approach best fits your security profile.
Some possible approaches:
Authorization free environments
Set up one or more of your pre-production environments without requiring Authorization on API calls.
Benefits:
Simple, relatively low cost way to build up fast running high coverage API tests to validate your code is behaving as planned.
At a bare minimum you should also check that calls to these endpoints on production fail.
Problems:
If these tests are running on anything other than your first integration environment, your feedback is slow when something breaks.
Your test environment is BY DESIGN not the same as your production environment and it is likely that you will eventually find that something that passes your tests fails with Authorization active.
From my perspective:
I strongly advise even having code checked in that could disable Auth on your production services.
Authenticate using a UI
It may be possible to use an automated browser to log in to the application and grab the auth key or cookie.
Benefits:
You might have already written code that automates logging in through the UI.
Problems:
Doing anything through the UI is going to be slow.
This also assumes that there is a simple means to grab the required Auth token from the browser.
You may not be able to work around a required biometric or MFA (multi-factor authentication) approach.
From my perspective:
You would have to be pretty desperate to do this, but if you do. Make sure that you can Auth once and then run ALL your tests. Do not generate a new Auth token for every test!
Add a backdoor test users
Work with your developers to write code to generate an Auth token programmatically.
Benefits:
If well written this should be fast.
Has the potential to authenticate as a range of users with different permissions and verify correct responses.
Problems:
This is BY DESIGN a security hole. How can you ensure that it cannot be used by others to bypass your security in production?
From my perspective:
You need some serious care, agreement with the development and security teams to ensure that any access you provide in this way is:
- Least privilege. (No superuser account)
- Restricted to defined QA users: I cannot emphasise this enough, How can you ensure that this can never be enabled for a general user’s account?
- Maybe display a warning if logged in to the UI using it?
Again, the further your test users are from regular users, the greater the risk that your tests pass code that fails with a real user. This is how test users work in Facebook Login. Facebook’s authentication service.
What about Authorisation?
I will be covering that next time. The good news is, once you have a fast, secure and effective means to Authentication for your tests, the rest is easy.
Final thoughts : TL/DR
For any controlled service, knowing who the user is (Authentication) and what rights they have (Authorisation / Authorization) are important, but from a testing standpoint, User authentication is by far the bigger problem.
There will have to be compromises between security and how truly you are actually testing the production code.
Do you have a better suggestion?
Please comment or get in touch if you have other suggestions I should include.
Lessons learnt:
- Authentication is the process of verifying which person or software is the one making calls to the API.
- Unless you are planning to manually login for your automated API tests you need to find someway to bypass Authentication for the users you will test with.
- Authorisation (or Authorization for my US readers) is the process of determining whether the user (or software) should be able to use your API
- I’m a strong believer that most companies should not write its own Authentication service. At least then you should have documentation on how to authenticate in tests.
A reminder:
If you want to ask me a question, Twitter is undoubtedly the fastest place to get a response: My Username is @AlexanderOnTest so I am easy to find. My DMs are always open for questions, and I publicise my new blog posts there too.