apigee: where do I correlate the keys with this policy - api-key

So I read this in the apigee documentation to understand how I can enforce an API validation policy . I am still confused on where this is correlating the keys with .
1) lets say I have an api key called key1 for a client . the
<VerifyAPIKey name="APIKeyValidation">
<APIKey>request.queryparameter.apikey</APIKey>
</VerifyAPIKey>
strips the api key from the request . Now my question here is how I should be correlating this key with key1 . any pointers / help with this is greatly appreciated .

You don't need to explicitly 'correlate' the API key. The policy actually validates the key for you. (In fact, sometimes you'll want to strip the API key using another policy--AssignMessage--after the key has been validated.)
The variable in the policy, 'request.queryparameter.apikey', just tells the API proxy where to look for the API key in the request message. Once it has located the key, it does the validation, and throws an exception if the key is not valid.
You can check out this sample for more:
https://github.com/apigee/api-platform-samples/tree/master/sample-proxies/apikey
Hope that helps.

Key validation in Apigee Edge is an integrated part of the platform, in the prior generation the key validation was done through an API.
The way it works follows this general flow
Key is Generated ( this can be done through a development portal or directly through the Enterprise UI)
Key is passed to API with a VerifyAPIKey policy
The VerifyAPIKey policy is configured to consume the key from part of the request, this can be a form param, header or query param.
<VerifyAPIKey name="APIKeyValidation">
<APIKey>request.queryparameter.apikey</APIKey>
</VerifyAPIKey>
The Policy Validates that the API key referenced is valid, if it is valid the policy will fill several variables that are useful for further processing.
If the key is invalid the policy will return an appropriate error.
If some of the data that is returned from the policy does not match some of your workflow assumptions you can use the raisefault policy with a condition matching your assumption
Here are some documentation pages that talk about these policies and how they work
http://apigee.com/docs/api-services/content/enforce-access-control-using-verifyapikey
http://apigee.com/docs/api-services/content/exception-handling-raisefault

Related

Rest API under https security

I am new and need directions so I can ask the correct questions. Here's the deal:
I have developed a REST API under HTTPS.
The user must provide a valid token to use the API.
The token expires after not being used for more than 5 minutes.
To obtain the token, the client must call the authentication API passing his private primary or secondary key, along with his user number.
Each key is unique, and on the database I save it's hash.
The user passes his primary or secondary key through the header with key "pk" or "sk" and "usernumber".
The server will get those keys and send to the database, which will apply the hash and check if they are valid.
Once the keys are valid, a token itself is generated on the database, and returned to the user.
My concern regards passing the primary key or secondary key on the headers. I am not sure if someone can obtain those data from outside and neither if it is the best practice. I am trying to get some directions, and I have came upon basic auth, oauth, and others. But they all seem to be on HTTP.
I have not found much about API HTTPS, so I also need some directions here. Can I make my API accept only https requests? If so, does the same security rules apply?
Thanks in advance.
There are 4 security aspects to consider. Most of the frameworks define the flow for Authentication and Authorization. Some frameworks define Integrity as well via Signatures.
But almost all heavily rely on encrypted data for for Confidentiality. i.e they recommend HTTPS if the communication is based on HTTP
Authentication:
Identifying who is talking to your API.
Authorisation:
Once you have identified who is talking to your API, ensuring they have the permission to talk to. If authentication is like checking someone's Id and allowing them into the building. Then authorisation is like allowing them to go into room for which they have access code.
Integrity:
One you know who are you talking to and what they are allowed to do, you still need to make sure that data you are receiving is from them and not tampered data.
Confidentiality
May be they are not tampering the data but reading all the data over the wire so later they can use that data and pretend to be the person you trust. So except for the sender and receiver no one else to see the data.
Note:
The above 4 aspects are for security on the flow.
You also have to consider security at rest. You seems to have strong design here on the server side for this aspect.
Have you considered what would you do when the token expires after 5 minutes. You user won't be happy entering user number and primary key/secondary key every 5 minutes. And if you plan to store it on client side so you can automate it every 5 minute, then you have to think about where would you store it in the client side and security at rest aspect for that
First of all: regarding HTTPS VS HTTP.
HTTPS is HTTP over TLS, where TLS is another layer of protection meant to secure the communication channel. All HTTP rules regarding headers apply to HTTPS too. TLS will protect your data confidentiality and integrity. It will protect the whole HTTP request including headers and body.
Regarding passing secrets as headers.
It's ok to pass secrets as headers or body. It's not ok, to pass secrets in URL. It's not ok to log out secrets on servers and proxies along the way. It's not ok to implement your own authentication mechanisms unless really needed.
If you want to read more about what is required to protect the communication channel (and the rest of the application), look into the OWASP Application Security Verification Standard.

Is there a way to secure an API key on a frontend page?

My service allow any HTML documents to be converted to PDF using a POST request.
It is mostly used on the backend of my client's server and thus, the API key used for the communication is kept private.
Now, I'm thinking of a way to let my client's visitors be able to call my service on behalf of my client API key, without exposing this secure API Key.
My main issue here is security. If my client add an XHR POST requests that contains the API key, someone can take that API key and use it for their own purpose and abusing my client's account.
I could filter by domain, but this is easily spoofed so it's not possible.
I was wondering if there was a way to call a private service and be identified without risking its identity to be stolen, from the client ('s client) side?
If you're providing this sublet for authenticated users, then it's fairly trivial to give them unique keys (something that hashes their user ID or session against the API key and an initial timestamp, and checks it / logs it / looks for brutes before accessing the API). If you're doing it on the open web, without any kind of user authentication, then rate limiting gets very tricky indeed. Generally you'd want to use a combination of session hashes, IP address, operating system and browser data to create an anonymous profile that gets a temporary key on the frontend. One fairly solid way to do this is to force users through a CAPTCHA before serving a temporary key that allows them a limited number of uses of the permanent key. Any user whose ip/browser/session matches the existing attributes of a known client key is shunted to that one (and gets to skip the CAPTCHA); anyone who doesn't match an existing profile gets the CAPTCHA. That makes you a less attractive target for spoofing. On top of that, you should always rate-limit the entire thing, within a reasonable number of hits per day based on what kind of traffic you expect (or can afford), just so you don't have any surprises. This is the minimal security you'd want if your client's money is on the line every time their API key is used. It will require a simple database to store these "profiles", track usage, check for brutes and maintain the currently valid client keys. Client keys should always be expired regularly - either with a time diff against when they were created, or a regular cron process, or a maximum number of uses, etc.
One other thing I frequently do is rate-limit based on a curve. If I think 5 uses per minute is reasonable, for example, then after 5 uses in a minute from a session, each usage adds a delay of a fraction of a second * the number of uses in the last minute, squared, before the data is served.
The best answer would be to put this all behind a login system and secure that.
Assuming that you are using OAuth kind of system, In that case, make use of Access Token Mechanism that provides access to private API/User's data on behalf of User(Client) without exposing his/her credentials or API Key(Authentication key), also the access token can be expired based on the time/usage.
Example: The access token is generated against a single endpoint that can be the Html Conversion endpoint and will be expired once the action completion.
https://auth0.com/docs/tokens/access-token
And following blog post would be helpful to architect your authentication system
https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
there is no good way to do front-end secure storage but my recommendation is :
is an API that used HMAC signing of requests in combination with OAuth authentication. The API key is actually a signing key. they key does not get transferred. The API key can still get found on the front-end but it becomes useless because you still need the OAuth token to send a valid request.
i know users will have to login in, but you can see this as an advantage because atleast you can log who is using the app by getting information from oauth.
please consider back-end secure storage!
You can use JWT tokens in my opinion. On the basis of username, password or any other info you can generate unique jwt tokens for different users.
Anyone can decipher these jwt tokens but not he unique security token.
If you want to add more more security to tokens, use JWE, encrypted web tokens.
More about these schemes can be found at https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3
Hashing is a decent option and should be done anyway, but for a fully secure method that wouldn't add too much complexity, you could simply abstract away from the authorization/API key by building your own API to interface with the API. This way you could both limit the kinds of things that can be done with the API key and also completely obscure the API key from the user
I don't think you should always go for user auth or JWT, it just doesn't fit all use cases. The idea of using a Captcha is interesting but also somewhat complex.
If complexity is not an issue I would rather use an infrastructure approach, I'm most familiar with AWS so I'll focus on that. Assuming you can change the host of your front end you can have your site hosted on an S3 bucket, served through a CDN, and create a proxy Lambda function that will hold the logic to call your API and store the API key as an encrypted environment variable. This Lambda you call through an API Gateway that can only be called by a specific IAM role which the S3 bucket also uses. You can also use a Cognito User Pool without authentication.
Going back to a simpler alternative the Captcha approach can be implemented as an attestation provider. I know of two services that do this, Firebase and KOR Connect. Due to Firebase using this approach only for their own resources as of the time of this writing I much rather use KOR Connect as it’s a very simple middleware that basically solves this issue. I won't go into detail about these services as it’s not the main concern of this topic but you can check the documentation their respective links.

Amazon Product Advertising API Scratchpad not working

So I've just been fighting shadows in the Amazon labyrinth. Went to use the Amazon Product Advertising API Scratchpad to test out my Access Key Id and Secret Access Key, as well as entering the Associate Tag which isn't used in critically in the API query, just important if you want credit for the query later.
I kept getting the following error, no matter how many times I went and created a new set of keys or verified them in the download section of the AWS Management Console for the root user - IAM users don't work in the API seemingly.
Error! SignatureDoesNotMatch
HTTP Status 403: Forbidden
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Rinse and repeat. Many, many times. Complete and utter frustration....
Lo and behold, I come across this oasis of sanity - Signed Request Helper - which provides a successful result to my query with the same keys as used above.
So, can anyone else confirm problems with the Scratchpad that didn't bear out in other applications, like the Signed Request Helper or their own code? At this point I'm betting that there is a bug in the Amazon Scratchpad. I guess I will go roll something to test in Python but the apparent craziness of the URL construction makes me wary. Seemingly it's soo hard even the Amazon guys got it wrong...
Yes, this reminds me of the dark days I had trying to get the signature just right.
I too had similar troubles when I started playing with the API. Ultimately, I ended up using the master credentials. This link will take you to the right spot after you login. Open the "Access Keys" tab. This is the area I made a new master access key for signing requests. When you get into the users/groups/roles/policies, I had trouble.
But I have a key there and I can use the scratchpad no problem. I have an application running that uses the key, but I just went and tried a query to confirm it's all still good.
Note that in the scratchpad the Associate Tag is irrelevant like you said. To get the error you have, it's for sure the SECRET ACCESS KEY that is incorrect. If you entered the ACCESS KEY ID field incorrectly, you would get this error:
Error! InvalidClientTokenId HTTP Status 403: Forbidden The AWS Access
Key Id you provided does not exist in our records.
For others who may come across this, let me impart my findings. Importantly, I was able to verify the keys with the Signed Request Helper but wasn't able to get the query to work in the Scratchpad. The error received clearly informs me that it is the signature that is wrong:
Error! SignatureDoesNotMatch HTTP Status 403: Forbidden The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
So one ponders, as instructed, on the Secret Key and the signing method. Since one is using the scratchpad, it must be the key. But the same key works in the signed request helper! What to do.
It turns out that the error was in one of the supplied parameters. If the scratchpad produces a signed url with a faulty parameter, it will result in that error. There is some validation going on, but you can still wind up with a bad parameter. So, if you get the above error, try a simple query with your key to prove that your secret access key is valid, then start investigating your supplied parameter values.

REST API and API KEY

Please someone explain me how to use an api key and what is it good for.
I have searched a lot about this and I got different and conflicting answers. One says that an API key is kept secret and its never sent as the part of the communication, while others send it to the client without any encryption. What is the client's signature? How can he generate it and what can do the server with it? Why should monkeying with api keys instead of using the good old username-password pair? Could someone explain me how the communications look between a client (Android device) and the server (php api) in detail.
I'd appreciate any good tutorials, code samples, and explanations for beginners.
The topic of API authentication is a complex one. Below I'm going to do my best to explain one part of the issue: why is an API key better than a username / password?
Here we go.
When building (or working with an API), a common question developer's ask is "Why does this service require an API key instead of my username and password?" It's a great question!
First, let's talk about what API keys typically are.
API keys are usually randomly generated strings of letters and numbers. Furthermore, an API key typically comes in two parts: an ID and a secret. If you're using a web service like Stormpath, for instance, you might have two API keys that look like this:
API_KEY_ID=kzjbOg3iOm4k4MRpBss76yxlZSPJtoOPaqxirsfX
API_KEY_SECRET=A8FnQWM7RpgGjU3sZjOUgMIq5t8mvAhQES9iE30S
You can think of an API key ID as a username. This is a globally unique identifier which allows the API service to find your account.
You can think of an API key secret as a password. This is a password that, when matched up with the correct API key ID, will grant you access to the API service in question.
The main reason you WOULDN'T want to use a username and password to authenticate against an API is that:
Even if the API is served over SSL, there are many exploits available which can compromise your credentials. If you used your username / password to log into API services, and an attacker grabs these credentials, they have access to your account as a whole.
If you use your username / password to authentication against an API, what happens if one of your servers / API clients is compromised? This means you need to reset your username / password and update it for all of the clients which are using it. This can be time consuming, and costly.
By using a username / password, you're usually restricting yourself to a certain type of API usage. By having API key pairs, you're able to separate out API credentials to different levels of access (maybe on key pair can only access certain data, while another can access other types of data).
API key pairs are, in general, a much better idea. In addition to the obvious security benefits, they also serve other purposes:
If an API key pair is leaked, you can usually create / cycle API key pairs without needing to update every single client you own.
You can use API key pairs to provide sub-account functionality for your API.
Hope that helps!
have a look at this
REST authentication and exposing the API key
Why do some API providers require an API key?
And study a lil about Oauth

What is an API key? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I see this word in almost every cross service application these days.
What exactly is an API key and what are its uses?
Also, what is the difference between public and private API keys.
What "exactly" an API key is used for depends very much on who issues it, and what services it's being used for. By and large, however, an API key is the name given to some form of secret token which is submitted alongside web service (or similar) requests in order to identify the origin of the request. The key may be included in some digest of the request content to further verify the origin and to prevent tampering with the values.
Typically, if you can identify the source of a request positively, it acts as a form of authentication, which can lead to access control. For example, you can restrict access to certain API actions based on who's performing the request. For companies which make money from selling such services, it's also a way of tracking who's using the thing for billing purposes. Further still, by blocking a key, you can partially prevent abuse in the case of too-high request volumes.
In general, if you have both a public and a private API key, then it suggests that the keys are themselves a traditional public/private key pair used in some form of asymmetric cryptography, or related, digital signing. These are more secure techniques for positively identifying the source of a request, and additionally, for protecting the request's content from snooping (in addition to tampering).
Very generally speaking:
An API key simply identifies you.
If there is a public/private distinction, then the public key is one that you can distribute to others, to allow them to get some subset of information about you from the api. The private key is for your use only, and provides access to all of your data.
It looks like that many people use API keys as a security solution. The bottom line is: Never treat API keys as secret it is not. On https or not, whoever can read the request can see the API key and can make whatever call they want. An API Key should be just as a 'user' identifier as its not a complete security solution even when used with ssl.
The better description is in Eugene Osovetsky link to: When working with most APIs, why do they require two types of authentication, namely a key and a secret?
Or check http://nordicapis.com/why-api-keys-are-not-enough/
An API key is a unique value that is assigned to a user of this service when he's accepted as a user of the service.
The service maintains all the issued keys and checks them at each request.
By looking at the supplied key at the request, a service checks whether it is a valid key to decide on whether to grant access to a user or not.
API keys are just one way of authenticating users of web services.
Think of it this way, the "Public API Key" is similar to a user name that your database is using as a login to a verification server. The "Private API Key" would then be similar to the password. By the site/databse using this method, the security is maintained on the third party/verification server in order to authentic request of posting or editing your site/database.
The API string is just the URL of the login for your site/database to contact the verification server.