How to restrict user password OAuth token within role in WSO2IS - wso2-identity-server

I have a basic question. Usually we configure user activities & permissions (basically Scopes) based on specific roles. If we have two roles like Manager and Employee, user in Manager role can have scope - 'Create Employee', 'Delete Employee'.
A user in Employee role will not have this right. He will have only 'View Employee' option. I have created two roles in WSO2 Identity Server as Manager and Employee. How can I assure Scopes such as - 'Create Employee', 'Delete Employee' are assigned to Manager. Employee role will have only 'View Employee' scope permitted ? Can I do this mapping in WSO2IS ?
Also when I try to call Auth2 token with grant Type as user password,
curl -k -X POST https://localhost:9443/oauth2/token -H 'Authorization: Basic <base64encoded(client_id:client_secret)>' -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=password&username=<username>&password=<password>&scope=<scopes>'
We need to mention scope as shown above. How will I make sure user with Employee group will not get token with 'Create Employee', 'Delete Employee' scopes? When the user in Employee role request for token user can mention any Scope. Is there a restriction we can enforce, so that user will not ask for OAuth token with Scope, for which the user don't have rights?
This is basic design question? This question thrown to me during one of my design discussion.

We can use Role based scope validator to do restrict OAuth2 scopes with user roles.
First, you have to register the scopes with their respective roles [1].
curl -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" -d '{"name": "profile", "displayName": "profile", "description": "get all profile information", "bindings": ["role1", "role2"]}' "https://localhost:9443/api/identity/oauth2/v1.0/scopes"
Then you have to enable the role-based scope validator inside the OAuth2/OIDC config section of the service provider.
After that, the requested scopes are allowed only if the user is having the respective role for that scope. Other token requests will be rejected.
[1] https://docs.wso2.com/display/IS550/apidocs/OAuth2-scope-endpoint/#!/operations#ScopeManagement#registerScope

Related

Is it possible to revoke a tapkey grant via POST request?

curl -X "POST" "https://my.tapkey.com/api/v1/owners/xxx/grants/xxxx/revoke" \
-H 'Authorization: Bearer xxxx'
I get
{"Message":"The requested resource does not support http method 'POST'."}
I created a grant and I wanted to delete it because I was testing. I thought that revoke can be something similar. I guess I am wrong about the grant concept here.
Is there a way to delete grants?
Why the error message is telling me that the revoke endpoint does not support POST?
As specified in the documentation for this endpoint, you need to specify dryRun query parameter.
https://my.tapkey.com/api/v1/owners/xxx/grants/xxxx/revoke?dryRun=false

Can I set the scopes when creating an access token using `gcloud auth`

I see in example Java codes there are possibilities to add scopes when one is requesting a refresh of a token:
credential.createScoped(Arrays.asList("someapi")).refreshToken
I saw the same in Python. But there is no configuration option for scopes in the cli.
gcloud auth application-default print-access-token
There is no gcloud auth --scopes="someapi" application-default print-access-token
Do you know how do I set up an access key for custom scopes in the cli?
In the API, as in the gcloud auth print-access-token command, if you set a scope on a user account, it will fail. Only the service account can be scoped, not the user account.
In fact you can set scope on your user account credential like that gcloud auth application-default login --scopes=... And then, when you will generate a token, it will be automatically scoped correctly.
Keep in mind that you especially need to scope your credentials to access to no Google Cloud API (Workspace, Maps, Youtube,...)
I believe requesting custom scopes through the gcloud auth application-default print-access-token command is not available by design.
The reason is that you can login to Google Cloud SDK with either a user account or a service account. If you are logged in to a user account using gcloud auth application-default login, the Cloud SDK only requests for scopes for full access to GCP APIs.
Thus, when you run gcloud auth application-default print-access-token, the Google Cloud SDK does not have access to any APIs other than GCP through your logged in account and thus, it can't print an access token with custom scopes.
The following tool helps obtaning a Bearer token that is working with the API:
oauth2l header --json PATH_TO_SERVICE_ACCOUNT_KEY businesscommunications
[ brew install oauth2l or https://github.com/google/oauth2l ]

User with Owner Role in Google Cloud gets 403 when Using Gmail Api

With gcloud I am logged into a terminal window with my email address, me#gmail.com. This project has the Gmail API enabled, and I am owner of this config. gcloud auth list shows
`Active Account`
`*me#gmail.com`
gcloud projects get-iam-policy $PROJECT shows that me#gmail.com as owner
I have an Oauth client/secret created in the project. My intent it to generate an access token to authenticate to the gmail API via the terminal with
`curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://gmail.googleapis.com/gmail/v1/users/me/labels`. (me is my actual email address)
Doing so gives me a 403. I can, however, use https://developers.google.com/oauthplayground/
and get a token with my particular scopes fine. Do I need to pass the Oauth Client Id to print-access-token? Why wouldn't owner have permissions over all possible actions in an API that's enabled?
EDIT: I have tried logging with auth application-default credentials as well with the same result.
TIA
You don't have the correct scope. You need to correctly scope your credential. Start by using this command to add the scope that you want in your credential
gcloud auth application-default login \
--scopes='https://mail.google.com/',\
'https://www.googleapis.com/auth/cloud-platform'
Then use the application-default access_token to call your service
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
https://gmail.googleapis.com/gmail/v1/users/me/labels`. (me is my actual email address)
It should work better.

Calling the IAM API but getting error - "Method ListRoles not found for service iam.googleapis.com"

I am trying to call the IAM api using curl, specifically the organizations.roles.list method.
https://cloud.google.com/iam/reference/rest/v1/organizations.roles/list
From the docs, my request should be constructed like this:
https://iam.googleapis.com/v1/organizations/<org-id>/roles
However, calling it results in this error:
{ "error": {
"code": 404,
"message": "Method ListRoles not found for service iam.googleapis.com",
"status": "NOT_FOUND" } }
Full request: curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://iam.googleapis.com/v1/organizations/<org-id>/roles
What am I doing wrong?
According to the docs, the endpoint https://iam.googleapis.com/v1/organizations/<ORG_ID>/roles is used to list the roles defined at the organization level (i.e. custom roles).
To get the list of default roles (pre-defined roles, curated roles, whatever you want to call them...), you must call the API without specifying any resource:
curl -H"Authorization: Bearer $(gcloud auth print-access-token)" https://iam.googleapis.com/v1/roles
So, to get the complete list of roles in your resource (be it a project or an organization), you have to get the curated roles and aggregate them to the custom roles defined at the resource level, and the custom roles defined on the parent resources (so, to get the roles in a project, you get the curated ones+project custom roles+parent org custom roles).
As to the error you were receiving, I'm not receiving it now when testing it. I've run some tests and I'm receiving:
403 when I don't have the proper permissions
200 with empty response ({}) when there are no custom roles defined
200 with a list of roles as defined in the docs when there are custom roles defined in the resource
Since the question is from Jul '17, and the custom roles started their beta on Sep '17, I'm assuming you were too quick to test the API, and that's the reason for the 404 you were receiving.

Permission Denied When Making Request to GCP Video Intelligence API

so I am able to make a valid request to the video intelligence api with the sample video given in the quickstart. https://cloud.google.com/video-intelligence/docs/getting-started I have tried many different ways of authenticating to the api as well. The API token I am using was created from the Credentials page in the console. There are no options to tie it to the video api so I figured it should automatically work. The API has been enabled on my account.
export TOKEN="foobar"
curl -XPOST -s -k -H"Content-Type: application/json" "https://videointelligence.googleapis.com/v1beta1/videos:annotate?key=$TOKEN" --data '{"inputUri": "gs://custom-bucket/IMG_3591.mov", "features": ["LABEL_DETECTION"]}'
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
curl -XPOST -s -k -H"Content-Type: application/json" "https://videointelligence.googleapis.com/v1beta1/videos:annotate?key=$TOKEN" --data '{"inputUri": "gs://cloud-ml-sandbox/video/chicago.mp4", "features": ["LABEL_DETECTION"]}'
{
"name": "us-east1.18013173402060296928"
}
Update:
I set the file as public and it worked. But I need to access this as private, so I gave the service account access to the file and tried to get the API key like suggested.
export TOKEN="$(gcloud auth print-access-token)"
curl -XPOST -s -k -H"Content-Type: application/json" "https://videointelligence.googleapis.com/v1beta1/videos:annotate?key=$TOKEN" --data '{"inputUri": "gs://custom-bucket/IMG_3591.mov", "features":["LABEL_DETECTION"]}'
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developers console",
"url": "https://console.developers.google.com"
}
]
}
]
}
}
It seems like the token returned by this print-access-token function does not work. I do have an API key, but it does not have access to the bucket and I don't see a way to give an API key access.
Update 2:
So it looks like we were setting our token wrong. We were following this example https://cloud.google.com/video-intelligence/docs/analyze-labels#videointelligence-label-file-protocol which is where we got the apiKey=$TOKEN from. But it looks like we needed to set the Bearer Header. We did try this at first but we were having the first issue of not having access to the bucket. So thank you.
TL;DR - Video Intelligence service is unable to access the file on your Cloud storage bucket because of lack of permissions. Since the API uses the permissions of the service account token being passed, you will need to grant your service account permissions to read the file in the GCS bucket or the entire GCS bucket itself.
Long version
The access token you pass should correspond to an IAM service account key. The service account will belong to a project (where you need to enable the Video intelligence API access) and the service account should have permissions to access the GCS bucket you're trying to access.
Each such service account has an associated email id in the form SERVICE_ACCOUNT_NAME#PROJECT_NAME.iam.gserviceaccount.com.
In Cloud console, you can go to the Cloud storage bucket/file and grant Reader permissions for the IAM service account email address. There is no need to make this bucket public.
If you use gsutil, you can run the following equivalent command:
gsutil acl ch -u SERVICE_ACCOUNT_NAME#PROJECT_NAME.iam.gserviceaccount.com:READ gs://custom-bucket/IMG_3591.mov`
I confirmed this myself with an IAM service account that I created in my project and used this to invoke the video intelligence API. The file was not made public, but granted Reader permissions only to the service account.
I used gcloud to activate the service account and fetch the access token, although you can do this manually as well using the google OAuth APIs:
gcloud auth activate-service-account SERVICE_ACCOUNT_KEY.json
export TOKEN="$(gcloud auth print-access-token)"
The steps for creating the IAM service account using gcloud are in the same page.
I can repro this issue. I believe the problem is that you don't have proper permission setup for your video file in your gs bucket. To test out this hypothesis try sharing it publicly (checkbox next to the blob in Google Storage) and then run the request again.