Expiration of accountId in Rest API - rest

Before first sending signing request I should get a accountId.
So is there any expiration time for this accountID? Can I save it and use it any time with unlimited time if there is no changes in credential or/and other api key and so on?
I can't find information about strategy for accountId in rest api documentation.
Thank you
ref:
https://www.docusign.com/developer-center/recipes/request-a-signature-via-email
https://www.docusign.com/p/RESTAPIGuide/RESTAPIGuide.htm#REST API References/Login.htm

The account ID is part of your developer account. You can find it when you login by clicking on the little down arrow in the top right corner next to your avatar. It will display your name the name of the company then a number. That is the account ID.
The account ID does not expire. The way DocuSign manages access to the API's is through an Integrator key. For information about the Integrator key please refer to the following link. https://www.docusign.com/developer-center/api-overview
So from a broad overview you would want to break up the different business processes by business group and have a different Integrator Key for each unit. That way if someone builds bad code or something strange happens and they turn of one of the Integrator keys it does not affect every group in the company.

There is no expiration of your accountId however note that it will change between environments - i.e. when you move from demo to production. Therefore the best practice is to write your integration such that, for a given user, it makes the login call then uses the accountId returned from that in subsequent API requests. By writing it this way you also make the go live process easier since you wouldn't have to remember to go back and change any hard-coded values in your app.

Note that when you are in production, your organization (or your customers' organizations) may well have more than one account id. And that individuals within the organization may well have access to more than one account.
Example: a company has different rules for electronic signature requests that are sent from the legal department and all the other corporate departments. Depending on the differences in the rules, the best DocuSign configuration may be to establish two different accounts, one for legal and one for everybody else. And some people may have access to both accounts.
Bottom line: when your API integration app logs in, it should enable either the human or your config file to specify the account that should be used (if the user has access to more than one account.) While all users have a "default account," it is not always the case that the default is the one that should be used by your integration.

Related

What is the best approach to stop your platform's users to "sniff" the frontend requests to backend and modify them?

So I have a platform that works like this: Users can create accounts by logging in with their Google (I USE AUTH0) and then they can create "Projects" which contain lots of other unimportant stuff regarding my current problem (like todo lists, ability to upload files etc; they can also Edit the project by changing some of it's attributes like name, description, theme and so on). There is a home page where everyone can see each other's projects and access them (but not upload files, change the tasks in the to do lists; this is possible only by the person that owns it).
By using a tool like Burp, people can see the request made from frontend to backend, for example when accessing one of the projects, and modify it on the fly.
This is what it looks like inside Burp when they access one of the projects:
As you can see there is a Get request to /projects/idOfTheProject; they can replace the GET with DELETE for example and they will successfully delete it; they can also see what is sent to the backend when a project is edited (name changed, description, thumbnail picture etc) and change anything they want about it.
How should I prevent this?
What I've looked at so far:
a. JWT - Probably the best fitting for my situation, but required the most work to be done (as I already have my platform almost finished with no such a security measure implemented yet, so I may need to rewrite a lot of things in both backend and frontend)
b. Sending the user's id that initiated the action as well to the backend and verify if it has the necessary privileges - the worst solution as users can access each other's profile and see the id, then just change another field in the request's JSON
c. Have a sort of token for each user and send that instead of the user's id - in this way somebody can't get your token by just looking at the communication between frontend and backend (only if it is using YOUR account). That token should be taken maybe somewhere from the auth0 when they create their account? If they provide something like that; or I can just create it myself and store it alongside the other user variables. You would still see the requests in plain text but even if you modified something you would still have to "guess" the owner's token, which will be impossible.
For frontend I use NextJS and for backend Flask.
Thank you in advance!
The TL;DR is that you don’t. A determined user will always be able to see what requests are being sent out by the code running on their computer and over their network. What you are describing when asking how to prevent people from “sniffing” these requests is security through obscurity, which isn’t actually secure at all.
What you should do instead is have an authorization system on your backend which will check if the current user can perform a given action on a given resource. For example, verifying that a user is an administrator before allowing them to delete a blog post, or making sure that the current user is on the same account as another user before allowing the current user to see details about the other user.

Single Sign On: Is it necessary/preferred to keep a table of linked accounts?

I build websites and authentication/account management systems. In our database, we have an user table that (conceptually) looks
TABLE: USER
id | name | email_address (unique)
====|===========|=========================
88 | Ben Ghazi | bgazi#gmail.com
We wanted to allow Single-Sign-On from Google. So we added a Database table that (conceptually) looks like this:
TABLE: SSO_LINK
id | our_account_id | sso_provider_name | sso_provider_account_id
====|================|===================|=========================
99 | 88 | GOOGLE | xyz983
The row in the above table indicates that if Google account #xyz983 ever tries to login, we should log them in as our user #88.
I'm now implementing Google SSO on a new project from scratch. I'm designing how it will work. I am realizing that perhaps this SSO_LINK table was completely unnecessary. Instead of maintaining a list of linked accounts and checking against it, we could just match the email address that Google provides us. If that email matches any of our users, then simply log that user in. That should work. Right?
However, I suspect that most serious implementation of SSO maintain the SSO_LINK table. What is best practice in this case and why?
Well, it depends.
In a simple world , you must take the token part as a successfull user authentication and check if the email is ok, then, you can proceed further and logged in your user.
In an enhanced and secured way, few tips :
You can check the data around the connection if it smells logical about that user :
in the middle of the night, we usually sleep
in this is a new device/computer/cellphone inside a country
reputed for bad users or an ip of any monkey private or public WLAN
used as open proxies or anything like that.
You can use any verifier service provider is a good way yo authenticate your users, but there is another ways : LDAP protocol with OpenLDAP (Free, Open Source Software) or Active Directory (if you are using a Windows Server).
Please, I hope your are hashing or crypting with strong algorithms user passwords and use a smart secured system of your own to not expose privacy concerns. If you are doing that well, you're better than some very big IT companies in USA/Europe. Time is money and user concerns are not their concerns until the RGPD has raised inside the law, so we are working a lot about that since years, and we will continue.
It is recommended to have an accounts and linked_accounts table as you suggest. But how account linking works will vary depending on the provider and the customer use case.
EXAMPLES
At Curity we support many types of authenticator:
Some are standards based identity providers, OpenID Connect or SAML
Some have vendor specific behavior
Some are not IDPs but need to map an identifier, eg a WebAuthn key, to a user account
TECHNIQUES
Sometimes you can deterministically match based on a field such as email, if you are sure that they are the same in both cases. In such cases you can run scripted logic to link accounts, as in this Sign in with Apple tutorial, which matches by email.
Note that there are peculiarities to how this provider works, and not all providers will give you an email. Access to Personally Identifiable Information (PII) is a hot topic these days.
In order for account linking to be reliable, you will sometimes need to involve the user, eg to prove their identity via passwords when they first sign in using a different method, so that you can link the provider specific ID to the user account.
SUMMARY
Account linking, like many other areas of Identity and Access Management, is a toolbox, rather than an out of the box solution. Extensibility features, including custom fields, are often needed. One step at a time though - start by getting the data structure broadly correct and then adding support for one provider at a time.
As a final point, storing the provider's subject claim is more stable than matching on email, since it copes better with future scenarios where the email changes, eg if the user marries.

Making API requests to a 3rd party that requires authentication

Here is my scenario. Imagine there is a Yoga studio that uses a professional booking and reservation system that exposes an API. Through this API an application can make a reservation for a client. The API takes the client's userid and password to make the reservation. The booking API doesn't use OAuth or any social media sign-ins.
My desire is to create an Assistant Action that would retrieve the list of classes and allow the client to make a booking.
My puzzle is what design/architecture to look towards to supply the userid/password pair required by the booking API.
How have others solved this puzzle?
Should I store the userid/password as "user state" associated with the action?
First, you should have a conversation with the API provider about why they don't provide an OAuth-based solution. This is a security vulnerability waiting to happen, if it hasn't already.
Second, you need to think very carefully about your own risk profile in this case:
Google does not allow you to collect credential information (ie - passwords) through your Action.
Because of this, you must use Account Linking to authenticate them.
This means that you will need something (ie - a database or data store) to manage their account on your side.
This database would be a good place to keep the username/password you need to use for them for the API...
...but it now means that you need to take extreme care about protecting this database.
You don't really say how this API allows for accounts to be created and managed. If these accounts are just used for you (ie - the user doesn't necessarily see them), then you can mitigate some of that risk by treating the username/password as an opaque token that you manage and generate and that the user never sees.
If this is something that the user is aware of, then you'll need to approach the account linking in one of two ways:
Have them log into your service via an app or webapp using this credential info that you will need to save (ack!) and then link to the Assistant using OAuth.
Have them log into your service via an app or webapp using Google Sign-In, which will carry over to your Action. Then have them provide the credential info for the API, which you will need to save (ack!).

REST API design: one endpoint with if/else logic or two separate role based endpoints

I have an API design/versioning conundrum.
Let's say I have an endpoint /api/customers which GETs all customers (ignore pagination). There's a twist though: if a regular user accesses this endpoint, they will only get the customers created by that user and no one else (I can check the access token and the sub field to determine who sent the request). Other usecase: if an admin accesses this endpoint, they should get ALL customers, regardless of who acquired them.
Now my question is from an API design perspective: is it better to have an if/else role check within the API controller itself to determine do I return ALL (admin) customers or specific (user) customers, OR should I differentiate between endpoints for the user and admin? I.e. admin only endpoint for all customers would be /api/admin/customers and regular users can still access their /api/customers?
In REST, it is normal to have multiple resources that share the same representations.
For example, the "authors' preferred version" of an academic paper is a mapping whose value changes over time, whereas a mapping to "the paper published in the proceedings of conference X" is static. These are two distinct resources, even if they both map to the same value at some point in time. The distinction is necessary so that both resources can be identified and referenced independently. A similar example from software engineering is the separate identification of a version-controlled source code file when referring to the "latest revision", "revision number 1.2.7", or "revision included with the Orange release." -- Fielding, 2000
It is perfectly consistent with that approach that you might have one resource for "all users", and another resource for "users created by Bob".
Where things get twisty is the case where you want to use the same resource identifier to provide different representations. That is, when Alice looks at "users created by me", she sees "users created by Alice", and when Bob looks at "users created by me", he sees "users created by Bob".
One possibility is to have "users created by me" redirect to the appropriate resource. It works, for values of "works" that permit extra round trips when the destination resource isn't already in the local cache.
In HTTP/2, server push may spare you some of that round trip pain.
The rules for shared caches should protect you from sending Alice's view of the "me" resource to Bob, and vice versa, but it is useful to be aware of the meanings of the various headers so that you don't inadvertently disable that protection.
Having different resources can be a problem in some "read your own writes" settings, because the caches won't know that an unsafe request has invalidated both resources. Bob creates a new user via a POST to "users created by me", and the corresponding cache entry is invalidated... but "all users" is a different cache key, and does not get invalidated. So if Bob looks at the all users view, he may see a previously cached copy without the changes that he just saw in his own view.
In some cases, it can make sense to consider sub-resources.
/api/customers
/api/customers#created-by-Alice
/api/customers#created-by-Bob
But if you are trying to reduce the amount of irrelevant data being exchanged, then that's not a good fit.
It should be same endpoint. Otherwise, each front-end which calling your API must have the same logic to determine the role and endpoint mapping.
It depends on your project.
If there's only 2 cases as you mentioned
only get customers created by that user for regular users
get all customers for admin users
then, it'd be better to use 1 endpoint by adding middleware to check current user role.
If you're plan to extend your project.
e.g. if admin users are also needed to get the customers created by that user, it'd better to create 2 endpoint. one for all customers, another one for current user's customers. like - api/customers/all, api/customers/me
I think /api/customers is fine for the cases mentioned. It's analogous to a web page request to index.html returning different content to different users.
If you want to extend it (e.g. Alice requesting Bob's list), you could support optional query params:
/api/customers?accessibleTo=bob
/api/customers?createdBy=bob
This would likely require an authorization check (Does Alice have access to Bob's list?), returning 403 (or 404, depending on your philosophy) when not authorized.
Also don't forget about caching. Avoid the possibility that two requests to the same URL (/api/customers) for different users will result in one user getting the other's list.

Handling User Preferences/States in REST API

We're starting to migrate our Website to a REST Service based system and are in the process of developing the core right now.
In our current setup a user has one or more "accounts" assigned which define what data he can see on the website. Only one account can be active for a given user at any time. Right now we store the selected account in the database and use it to filter all queries.
Now I'm not sure how to handle this properly in a REST environment. Possible solutions I found are:
Sending the requested account with every request
Storing the current account in the auth token. (We're using JWT for that)
Having the current account stored on the server and calling a specific resource to change it
Each of these has its pros and cons for our setup. Currently we're using the 3rd approach in our Website. But what would be the correct way to handle such a thing in a REST environment?
Yea the design you are dealing with is fairly bad, and what you really want to do is remove the state completely out of this system.
For that reason the first option is by far superior:
Sending the requested account with every request
If this is simply an id, there's a very simple way to do this, just prefix all your (relevant) routes / uris with this account id. For example:
http://api.example.org/accounts/{id}/...
This way the 'state' is maintained by virtue of which url you are accessing, and the server can be unaware of the state.