How to Secure CloudMonitor API Call using API Signature on Alibaba Cloud ECS - alibaba-cloud-ecs

CloudMonitor APIs in Alibaba Cloud ECS belong to the RPC type and can be called CloudMonitor APIs by sending HTTP requests.
I am calling QueryMetricList to query the monitoring data of ECS instance using this command.
http://metrics.cn-hangzhou.aliyuncs.com/?Action=QueryMetricList
&EndTime=2017-05-17+11%3A30%3A27
&StartTime=2017-05-17+11%3A20%3A27
&Period=60
&Dimensions=%7B%22instanceId%22%3A%22i-abcdefgh123456%22%7D
&Timestamp=2017-03-22T09%3A30%3A57Z
&Project=acs_ecs_dashboard
&Metric=cpu_idle
How to authenticate each API request through the API signature.
I appreciate any assistance with this.

To authenticate API request via the API signature you need Access ID and Access Key Secret.
Let me consider the Access ID and Access Key Secret as Key and Value respectively:
Your request before adding the signature:
http://metrics.cn-hangzhou.aliyuncs.com/?Action=QueryMetricList
&EndTime=2017-05-17+11%3A30%3A27
&StartTime=2017-05-17+11%3A20%3A27
&Period=60
&Dimensions=%7B%22instanceId%22%3A%22i-abcdefgh123456%22%7D
&Timestamp=2017-03-22T09%3A30%3A57Z
&Project=acs_ecs_dashboard
&AccessKeyId=Key
&SignatureMethod=HMAC-SHA1
&Metric=cpu_idle
AccessKey Secret is value, and the key used for HMAC calculation is value&. Then the signature value is calculated.
Add the signature value to the above API Request.
For instance, Let me consisder signature = "sdsdfasdfa" then the request will be:
http://metrics.cn-hangzhou.aliyuncs.com/?Action=QueryMetricList
&EndTime=2017-05-17+11%3A30%3A27
&StartTime=2017-05-17+11%3A20%3A27
&Period=60
&Dimensions=%7B%22instanceId%22%3A%22i-abcdefgh123456%22%7D
&Timestamp=2017-03-22T09%3A30%3A57Z
&Project=acs_ecs_dashboard
&AccessKeyId=Key
&SignatureMethod=HMAC-SHA1
&Signature="sdsdfasdfa"
&Metric=cpu_idle

Related

Azure API Management & Function Apps - Only allow APIM access to apps with user assigned identity

Currently I am using a backend connection with a function key in the header to access my function apps. Instead of needing to store & pass around these keys, I would like to use a managed identity to implicitly grant access to my API Management, and reject any direct calls.
I've read through this and it seems that I should be able to do this by doing the following:
Create User Managed Identity
Give it Contributor role to all of my function apps
Assign it to my API Management
Update the API Policy to include the following:
<authentication-managed-identity
resource="${function_id}"
output-token-variable-name="msi-access-token"
ignore-error="false"
client-id="#{function_access_client_id}"
/>
Where
a. "function_id" is the ID of my function app (also tried https://management.azure.com/)
b. "function_access_client_id" is the ID of my User Managed Identity
And this is where I now am confused.
If for (a) I use https://management.azure.com/, then i am able to successfully get a token, but it fails to authenticate against the "Authentication" of the function app.
If for (a) I use the ID of the function app, then i receive the following error:
"errorResponse": "System.InvalidOperationException: [MSAL] Authentication failed for ClientId: <user managed client id> Certificate: <certificate> AuthorizationUrl: https://login.windows.net/<id> resourceId: /subscriptions/<subscription>/resourceGroups/<res group>/providers/Microsoft.Web/sites/<function app name> ---> Microsoft.Identity.Client.MsalServiceException: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope /subscriptions/<subscription>/resourceGroups/<res group>/providers/Microsoft.Web/sites/<function app>/.default is not valid.
I am able to make this work if I set the client_id variable to be the value of the Authentication Identity Provider of the function app. I also noticed that if I remove the user managed identity from the API Management after this worked, then it fails because it says that APIM doesn't have management identities enabled.
I guess I'm just really confused with the logic of this. If this is set up correctly, that means I need
A user assigned managed identity to say I can access the application. This Identity can create it's own JWT using it's client ID, but we don't use it
An authentication on the function application requiring a JWT
A policy which references the client ID of the authentication listed in step 2.
Is this set up wrong? It works it just feels very odd. What's the point of user managed identity?

What is the best way to call an authenticated HTTP Cloud Function from Node JS app deployed in GCP?

We have an authenticated HTTP cloud function (CF). The endpoint for this CF is public but because it is authenticated, it requires a valid identity token (id_token) to be added to the Authorization header.
We have another Node JS application that is deployed in the same Google Cloud. What we want is to call the CF from the Node application, for which we will be needing a valid id token.
The GCP documentation for authentication is too generic and does not have anything for such kind of scenario.
So what is the best way to achieve this?
Note
Like every google Kubernetes deployment, the node application has a service account attached to it which already has cloud function invoker access.
Follow Up
Before posting the question here I had already followed the same approach as #guillaume mentioned in his answer.
In my current code, I am hitting the metadata server from the Node JS application to get an id_token, and then I am sending the id_token in a header Authorization: 'Bearer [id_token]' to the CF HTTP request.
However, I am getting a 403 forbidden when I do that. I am not sure why??
I can verify the id_token fetched from the metadata server with the following endpoint.
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=[id_token]
It's a valid one.
And it has the following fields.
Decoding the id_token in https://jwt.io/ shows the same field in the payload.
{
"issued_to": "XXX",
"audience": "[CLOUD_FUNTION_URL]",
"user_id": "XXX",
"expires_in": 3570,
"issuer": "https://accounts.google.com",
"issued_at": 1610010647
}
There is no service account email field!
You have what you need in the documentation but I agree, it's not clear. It's named function-to-function authentication.
In fact, because the metadata server is deployed on each computes element on Google Cloud, you can reuse this solution everywhere (or almost everywhere! You can't generate an id_token on Cloud Build, I wrote an article and a workaround on this)
This article provides also a great workaround for local testing (because you don't have metadata server on your computer!)

Azure APIM to azure function mutual authentication

I've created a HTTPTriggered azure function and I've setup the API management to call the function. Certificate validation policy is set in APIM and when APIM will forward the call to azure function the API-key of the function will be passed.
is this possible to put a client certificate validation also from APIM to function-App instead of the just API-key?
You need to add a property to the function app resource definition as described here for client certificate authentication to be enabled. You'll then need to do your own cert validation in the function code.
{
"properties": {
"clientCertEnabled": true
}
}
Inspect this header for the base64 encoded client cert:
X-ARR-ClientCert
One caveat here, it may not work with Consumption plans, i didn't get around to test it, please leave a comment if it does work.
Alternatively, you could grab a Bearer token from Azure AD with client credentials flow (client_id and client_secret) and call the function that way (enable EasyAuth for that to work). The bigger caveat here is also a question, can APIM do that flow for you? I have no clue.
Update:
Found something here, looks like it's doable with an outbound policy and makes a raw POST request into Azure AD, which is fine, since that's what that flow is really about.

HTTP Basic Auth and Azure Functions

In an in Azure Functions with HTTP trigger, where in the HttpRequestMessage instance are the credentials (username and password) in a basic HTTP Authentication scheme?
I was able to find a username:password string encoded in base64 in:
request.Headers.Authorization.Parameter
Where request is an instance of HttpRequestMessage
Basic is not an option, nor is any other commonplace auth scheme available right now, unfortunately. Other than Anonymous, HTTP Functions auth is based on keys generated and stored in Azure. Three types of keys are currently available:
Admin - requires a "host" key (host keys are shared by all functions)
System - requires the special "master" host key
Functions - requires a key defined for the individual function
Keys are documented here and can be managed from the "Manage" button when you expand a given Function in the portal.
Microsoft is working on adding a new token-based User auth type based on tokens instead of keys. You can read about it in the following github issue:
https://github.com/Azure/azure-functions-host/issues/33

AWS Lambda gateway API gives error message

I have created one API endpoint for lambda function, as - https://XXXXXXXXX.execute-api.us-east-1.amazonaws.com/XXXX/XXXXXXXXXXXX/ which is GET method.
While calling that endpoint from postman it is giving me
{
"message": "'XXXXXXXXX3LPDGPBF33Q:XXXXXXXXXXBLh219REWwTsNMyyyfbucW8MuM7' not a valid key=value pair (missing equal-sign) in Authorization header: 'AWS XXXXXXXXX3LPDGPBF33Q:XXXXXXXXXXBLh219REWwTsNMyyyfbucW8MuM7'."
}
This is a screenshot of the Amazon Lambda Upload Site: http://i.stack.imgur.com/mwJ3w.png
I have Access Key Id & Secret Access Key for IAM user. I used it all but no luck. Can anyone suggest tweak about this.
If you're using the latest version of Postman, you can generate the SigV4 signature automatically. The region should correspond to your API region (i.e. "us-east-1") and the service name should be "execute-api"
This is not a solution but it has helped me more than once:
Double-check that you are actually hitting an existing endpoint! Especially if you're working with AWS. AWS will return this error if you don't have the correct handler set up in your Lambda or if your API Gateway is not configured to serve this resource/verb/etc.

Resources