I am building a node.JS server which interacts with Microsoft APIs. The server deals with multiple applications created in Azure where each application will have a Client ID and Client secret configured. I have a logic that will switch between these credentials and query the appropriate Microsoft Application based on the organization of requesting user. My concern is about storing the Client id and Client secrets.
Initially, I had planned to store these in a YAML configuration file and read it, but then there can be Applications configured when server is running and also this method can't be efficient when the number of Applications configured is high.
My second option is to store these credentials in a database so that I can query them whenever needed, but this way, the person adding a new client might have to go through a learning curve to use database plus I do not want to expose my database passwords.
Is there a common practice to store a large number of sensitive application credentials like this?
You should look into dedicated secret storage. In Azure you can use the Azure Vault service for example. AWS has Secret Storage service, Google Cloud has Secret Manager.
If you use kubernetes for your deployment it has a built in cluster secret store.
You can also use a dedicated third party secret manager server / module such as Hashicorp Vault or Keywhiz from Square.
Related
Per my review of how to setup secure access to amazon s3 buckets it looks like we first generate an IAM user and then tie a security policy allowing s3 access to that user. After that we can generate API keys for the bucket, which can authenticate request for bucket access. That's my understanding at this point, please correct me if I missed something.
I assume the API keys should be server side only (The Secret Access Key). In other words it's not safe to place these directly inside the webapp? Hence we would first have to send the data to our server, and then once there we can send it to the bucket using the API key?
Is there any way to secure access directly from a web app to an amazon s3 bucket?
Approach Summary
Per the discussion with #CaesarKabalan it sounds like the approach that would allow this is:
1) Create an IAM user that can create identities that can be authenticated via Amazon Cognito - Lets call the credentials assigned from this step Cognito Credentials.
2) The user signs in to the webapp with for example Google
3) The webapp makes a request to the webapp's server (Could be a lambda function) to signup the user with Amazon Cognito
4) The webapp now obtains credentials for the user directly from Amazon Cognito and uses these to send the data to the s3 bucket.
I think that's where we are conceptually. Now it's time to test!
From your question I'm not sure what portions of your application are in AWS nor your security policies but you basically have three options:
(Bad) Store your keys on the client. Depending on the scope of your deployment this might be ok. For example if each client has it's own dedicated user and bucket there probably isn't much risk, especially if this is for a private organization where you control all aspects of the access. This is the easiest but less secure. You should not use this if your app is multi-tenant. Probably move along...
(Great) Use an API endpoint to move this data into your bucket. This would involve some sort of infrastructure to receive the file securely from the client then move it into S3 with the security keys stored locally. This would be similar to a traditional web app doing IO into a database. All data into S3 goes through this tier of your app. Downsides are you have to write that service, host it, and pay for bandwidth costs.
(Best) Use Amazon Cognito to assign each app/user their own access key. I haven't done this personally but my understanding is you can provision each entity their own short-lived access credentials that can be renewed and you can give them access to write data straight to S3. The hard part here will be structuring your S3 buckets and properly designing the IAM credentials for your app users to ONLY be able to do exactly what you want. The upside here is the users write directly to S3 bucket, you're using all native AWS services and writing very little custom code. This I would consider the best, most secure, and enterprise class solution. Here is an example: Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket
Happy to answer any more questions or clarify.
The API is a backend to a Web app and mobile app. I don't need user authentication. I simply need a way to secure access to this API.
I just need to ensure only web app and mobile app can talk to this backend and no one else.
If you are indeed using Google Cloud Endpoints, what you want is easy to do.
You need to log into the developer console and go under API Manager -> Credentials. There you can generate access keys for each of your clients. Then you add those tokens to your endpoints using the provided annotations. You cloud endpoints will only serve requests that come from one of the clients you have specified.
I would to ask a few questions to better understand some procedures. I'm trying to write a web api project which will be a backend for both web and mobile clients.
The problem that i've in mind is about security. I don't want to use Identity or any other providers. I want to use my own database user and role structures.
Only authenticated client applications should be consuming my application. So that anonymous applications should not consume it.
So what should be the approach ? I 've written a custom AuthorizationAttribute and check some custom headers like "AppID","AppSecurity" key which i store in my own database and if the client sends the right appId and the key it means the app is authenticated to consume the API which does not sound very secure to me.
Another issue is that ; Lets say i've developed a javascript web application and i've to first authenticate the application itself before making GET/POST/PUT/DELETE etc requests which means i've to add some kind of authentication data like username, appkey, password in one of the js files for sending the "AppID" and the "AppSecurity" keys in the header. A client who knows how to use some developer tools or fiddler can easily capture my header values that are being sent to the server side? Even if i pass authentication values on the body of my json request it still can be found on the js files that are sent to the client. I'm also confused about that tooƧ
So basically i want to build a server side api that will serve the data and get data from the authenticated client applications only. What i need is a simple example for that without using any identity providers.
I am developing an HTML5 mobile application which I am planning to port to Android also using Phonegap. I want to use AWS DynamoDB for storing my users data. I know that amazon has a http api but it is too complicated. Some of my queries are
If I use the HTTP api, wouldn't it expose my credentials? (Same qquery for dynode)
What are the alternatives? I have a EC2 instance so hosting a server is not a problem.
I would appreciate your suggestions on this.
If you connect directly from your phone application, to dynamodb, you will risk exposing your credentials.
The general way to handle this is to have a json REST api through which the phone application can authenticate and make requests to the datastore. Your application would communicate with this api.
In this case, each user would likely have its own authentication to your server application.
I am building an API and had questions about handling authentication when using a front-end framework such as Backbone.js.
I have a single API server that is responsible for returning and modifying data based on RESTful web requests.
I have another app server that is a Backbone application. I want this application to connect directly with my API server, so set the entire project up so that this app server can make cross-domain AJAX requests to the API server.
There are some API routes that I do not want unauthorized parties to obtain access to. For example, I have a path /users that lists all the users of my app. I need this path later on for admin functions, but I don't want it publicly available to my app server.
What is a good authentication scheme to use? OAuth won't work because the secret token would be exposed on the front-end. And after that, I'm a little stuck with what my options are. Does anyone have any suggestions moving forward?
In cases like these I use a combination of techniques.
-- Good ole Cookie based auth
As a backbone app will always be used inside a browser and browsers have built-in cookie support, I would suggest that you should accept cookie based sessions on the server side. All the auth related stuff will be handled by the browser and you don't have to worry about storing keys etc. On top many libraries like (NSURL in iPhone) and frameworks (like PhoneGap/Trigger) all support cookies so woha you can support all kind of clients with litte work.
-- Plain API Key
For third-parties, I use api-key based authentication. You provide username and password, I provide key. You send me that key every time in HTTP header for all subsequent requests. I use the key to identify you and then allow/disallow actions accordingly.
I assume once you can authenticate a user (wait..who are you?), then you can setup authorizations ( you say Micheal ? ...ok you can access /users )
Also take a look at my backbone-parse plugin for an idea on how to authenticate users against an external API service #shamelessplug