AWS AUTH0 DELEGATION ERROR Missing principal parameter (invalid_request) - amazon-web-services

While trying to fetch a delegation token from Auth0 to access S3 bucket on AWS I am getting this error:
{
"error": "invalid_request",
"error_description": "Missing principal parameter"
}
Here is the body of the request:
{
"client_id": "HIDDEN CLIENT ID",
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"id_token": "HIDDEN ID TOKEN",
"target": "HIDDEN TARGET",
"api_type": "aws",
"role": "HIDDEN ROLE ARN"
}

There could be other solutions but how I got it to work was to:
Replace,
"api_type": "aws"
With:
"api_type": "aws:s3"
OR:
"api_type": "aws:x" (where x is any AWS service code that you are trying to access!)

Related

How to add a Secret Manager read resource policy to my lambda resourse with SAM CLI template

I have a lambda function created from the SAM CLI template and it needs to call on the secret key manager to grab a third-party secret key. Since I want everything saved in a public GitHub I try to keep exposed information to a minimum which is why my initial secret that is added to the manager is blank and in theory I'd just update the value manually every time I re-create this SAM. The problem my lambda function doesn't have permission to call on getSecretValue(). I tried many different ways to add a policy but nothing worked.
Is there another way to get the ARN of my Secretkey recourse so I can pass it to the lambda Policies?
This is the error I get in cloudwatch when running a GET on the lambda (#### being placeholders)
"User: arn:aws:sts::######:assumed-role/FunctionRole-######/getAllItemsFunction-###### is not authorized to perform: secretsmanager:GetSecretValue on resource: Secretkey because no identity-based policy allows the secretsmanager:GetSecretValue action"
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Description",
"Transform": ["AWS::Serverless-2016-10-31"],
"Resources": {
"getAllItemsFunction": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "src/handlers/get-all-items.getAllItemsHandler",
"Runtime": "nodejs14.x",
"Architectures": ["x86_64"],
"MemorySize": 128,
"Timeout": 100,
"Description": "Description",
"Policies": [
{
"AWSSecretsManagerGetSecretValuePolicy": {
"SecretArn": {
"Ref": "Secretkey"
}
}
}
],
"Events": {
"Api": {
"Type": "Api",
"Properties": {
"Path": "/",
"Method": "GET"
}
}
}
}
},
"Secretkey": {
"Type": "AWS::SecretsManager::Secret",
"Properties": {
"Description": "Secret key from API that keeps API secure from outside calls",
"SecretString": "{\"secret\": \"\"}"
}
}
},
"Outputs": {
"WebEndpoint": {
"Description": "API Gateway endpoint URL for Prod stage",
"Value": {
"Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
}
}
}
}
The fix to my problem was I had the wrong SecretId name used in getSecretValue({ SecretId: NAME_HERE }).
lambda_functon.js
// I only had "Secretkey" before. Had to switch it to "Secretkey-ksjsnKDNSkGk"
const { SecretString } = await client.getSecretValue({ SecretId: "Secretkey-ksjsnKDNSkGk" }).promise();
To find the proper name go to
AWS Secret Manager -> Secrets -> Select your secret -> View details for "Secret Name"
my secret name was that NAME-#### for example Secretkey-ksjsnKDNSkGk
I received two different errors which made this hard to troubleshoot.
Locally it said CATCH_ERROR: ResourceNotFoundException: Secrets Manager can't find the specified secret.
Remotely it returned "User: arn:aws:sts::######:assumed-role/FunctionRole-######/getAllItemsFunction-###### is not authorized to perform: secretsmanager:GetSecretValue on resource: Secretkey because no identity-based policy allows the secretsmanager:GetSecretValue action"
I found my solution by Navigating to my CloudFormation stack and viewing the Template that AWS created based on the template I feed it via (template.yaml or template.json). It specified all the resources created and the roles for each resource. This clearly showed me that my template file was correct and the lambda has access to the specified ARN so its very helpful to checkout.
To find Navigate to CloudFormations -> Select your Stack -> Select template -> Toggle "View processed template" -> Find your resource name/role in the file. You will usually see RESOURCE_NAME which is what you created and RESOURCE_NAME_ROLE which was automatically created for me based on the policies I have my resources in the template.yaml / template.json file. This will show you if your policies are created correctly.
At that point, I realized it was something else hence investigated the Secret Manager Resource itself and saw the name mismatch

GCP API key is not valid in postman

I tried to create new dialogflow intent through postman. It is working in API Explorer but I can't able to connect dialogflow with postman. For doing this I have created some credentials,
New API key in GCP project
Oauth credentials in GCP project
Bearer token from google cloud SDK shell
Here I have used same API in postman but can't able to connect. How can I troubleshoot this?
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "dialogflow.googleapis.com"
}
}
]
}
}

401: Access denied. You are not authorized to read activity records

I am trying to test https://admin.googleapis.com/admin/reports/v1/activity/users/{userKey or all}/applications/{applicationName} in the browser using the API explorer utility but I am getting below error.
{
"error": {
"code": 401,
"message": "Access denied. You are not authorized to read activity records.",
"errors": [
{
"message": "Access denied. You are not authorized to read activity records.",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
]
}
}
I have enabled all the necessary API scopes for the OAuth client. below is the screenshot of the scopes that I have enabled for my client.
The user which I was using along with the service account didn't have proper permission to access some of these APIs. I switched to a subject user with all necessary permissions and it started working fine for me.

AWS API Gateway Custom Authorizer Role Validation

Is there any way of specifying allowed scopes on an API Gateway method such that the allowed scopes are passed to a custom authorizer and validated against the scopes claim in an access token.
E.g. a get users endpoint might be available to all users but a create user endpoint only available to an users with the create:user scope. As well as ensuring the access token is valid the custom authorizer would check the scope claim in the token and compare it to the allowed scopes for the method.
Would prefer not to have to write a different authorizer function for each combination of required scopes.
I notice something like this is possible with Cognito, but my identity provider / token issuer is Auth0 so using Lambda function to validate the access token
Kind regards
You should be able to use single Lambda Authorizer to protect both endpoints based on the token scope. You will want to use Request based Enhanced Lambda Authorizer
You pass the access token in the Authorization header and verify the access token signature and expiration before processing the request.
An example of Event object received by the authorizer:
{
"methodArn": "arn:aws:execute-api:us-east-1:XXXXXXXXXX:xxxxxx/dev/GET/hello",
"resource": "/hello",
"requestContext": {
"resourceId": "xxxx",
"apiId": "xxxxxxxxx",
"resourcePath": "/hello",
"httpMethod": "GET",
"requestId": "9e04ff18-98a6-11e7-9311-ef19ba18fc8a",
"path": "/dev/hello",
"accountId": "XXXXXXXXXXX",
"identity": {
"apiKey": "",
"sourceIp": "58.240.196.186"
},
"stage": "dev"
},
"queryStringParameters": {},
"httpMethod": "GET",
"pathParameters": {},
"headers": {
"cache-control": "no-cache",
"x-amzn-ssl-client-hello": "AQACJAMDAAAAAAAAAAAAAAAAAAAAAAAAAAAA…",
"Accept-Encoding": "gzip, deflate",
"X-Forwarded-For": "54.240.196.186, 54.182.214.90",
"Accept": "*/*",
"User-Agent": "PostmanRuntime/6.2.5",
"Authorization": "hello"
},
"stageVariables": {},
"path": "/hello",
"type": "REQUEST"
}
You can identify the request by combination of event.requestContext.resourcePath and event.requestContext.httpMethod. Based on the request type and the scope defined in the token you can return Allowed or Denied policy. If, for example, request is for create user endpoint but access token don't include create:user scope then you will return policy to deny the request.

How to get permission list using Keycloak Token

Can't get the User Permission list using Keycloak token. Getting error like keycloak.exceptions.KeycloakAuthorizationConfigError: Keycloak settings not found. Load Authorization Keycloak settings.
Iam using python-keycloak
Keycloak Configuration
keycloak_openid = KeycloakOpenID(server_url=config.server_url,
client_id=config.client_id,
realm_name=config.realm_name,
client_secret_key=config.client_secret_key,
verify=True)
keycloak_openid.load_authorization_config(os.path.join(local_path, 'Dynamic_Client-authz-config.json'))
userinfo = keycloak_openid.get_permissions(token, method_token_info='introspect')
print(userinfo)
Key Cloak Setting File
{
"allowRemoteResourceManagement": false,
"policyEnforcementMode": "PERMISSIVE",
"resources": [
{
"name": "Default Resource",
"type": "urn:Dynamic_Client:resources:default",
"ownerManagedAccess": false,
"attributes": {},
"_id": "2c2a046f-84b2-42a8-a028-c6ae56ad63a1",
"uris": [
"/*"
]
}
],
"policies": [
{
"id": "f570c7e7-8168-4fb8-b05c-4df8be9398d0",
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "js",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"
}
},
{
"id": "836d2453-ad1c-4482-b726-49875a8ba64f",
"name": "Default Permission",
"description": "A permission that applies to the default resource type",
"type": "resource",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"defaultResourceType": "urn:Dynamic_Client:resources:default",
"applyPolicies": "[\"Default Policy\"]"
}
}
],
"scopes": []
}
Please find the solution for my issue
so I am assuming you are looking for the roles?
If so use the introspect token , that worked for me
Introspect Token
token_info = keycloak_openid.introspect(token['access_token'])
print(token_info['resource_access']['client-name']['roles'])
I am able to get the permissions using UMA (mentioned here):
# Get UMA-permissions by token
token = keycloak_openid.token("user", "password")
permissions = keycloak_openid.uma_permissions(token['access_token'])
# Get UMA-permissions by token with specific resource and scope requested
token = keycloak_openid.token("user", "password")
permissions = keycloak_openid.uma_permissions(token['access_token'], permissions="Resource#Scope")
# Get auth status for a specific resource and scope by token
token = keycloak_openid.token("user", "password")
auth_status = keycloak_openid.has_uma_access(token['access_token'], "Resource#Scope")