Azure DevOps - Unable to Create Var Group using Azure DevOps API and Auth Token - azure-devops

Requirements: We would like to create a Variable Group (along with some variables) in a given Project.
Option1: We are able to create a new Variable Group successfully
when we create a request via PostMan using PAT Token which has FULL access.
Option2: Our end goal is to invoke the ADO Rest API in the Web App which uses
OAuth. When the end user logs in and make a call (pls see the input
details below) we are getting '401 Un Authorized - The user is not authorized to access this resource.' error. The Web App's application has the Variable Groups manage scope as shown below.
TroubleShooting: As part of troubleshooting, for Option1 which uses PAT (with full access) in Postman, we have updated the permissions of the PAT to just have Create, Read and Manage Var Groups as shown below.
Now, even the Option1 is not working after making the PAT to have Custom Defined access.
Are we missing something?
Postman Details:
URL: https://dev.azure.com/myorgname/_apis/distributedtask/variablegroups?api-version=6.0-preview.2
Verb: Post
Headers: Authorization: Basic
Body:
{
"name": "This is ignored",
"description": "This is ignored",
"type": "Vsts",
"variables": {
"BuildConfiguration": {
"value": "Release"
}
},
"variableGroupProjectReferences": [
{
"name": "VarGroup",
"description": "The variable group to store the information about the variables using in the Pipeline",
"projectReference": {
"id": "#ProjectId#",
"name": "#ProjectName#"
}
}
]
}

I can also reproduce your issue with option 1, not only Read, create, & manage for Variable Groups, even I select all the scopes via Custom defined, it still does not work.
According to this doc - https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/manage-pats-with-policies-for-administrators?view=azure-devops#restrict-creation-of-full-scoped-pats
Some of our public APIs are currently unassociated with a PAT scope, and can therefore only be used with “full-scoped” PATs. Because of this, restricting the creation of full-scoped PATs might block some workflows. We're working to identify and document the affected APIs and eventually associate them with the appropriate scope. For now, these workflows can be unblocked by using the allow list.
I believe this should be the reason for this issue, there may be some additional permissions to create variable groups. For option 2, there may be a similar cause.
So in this case, you may need to use the Full access PAT temporarily, as mentioned in the doc We're working to identify and document the affected APIs and eventually associate them with the appropriate scope.

Related

How to know the structure (body) of rest api azure POST request?

i am new at rest api azure and i dont know how to get correct body template of policy.
For example i used :
GET https://dev.azure.com/organization/project/_apis/policy/types?api-version=7.0
and the response are types of policies which i can use but how do i know the construction of the request body? Like this one:
{
"isEnabled": true,
"isBlocking": false,
"type": {
"id": "fa4e907d-c16b-4a4c-9dfa-4906e5d171dd"
},
"settings": {
"minimumApproverCount": 4,
"creatorVoteCounts": false,
"scope": [
{
"repositoryId": "a957e751-90e5-4857-949d-518cf5763394",
"refName": "refs/heads/master",
"matchKind": "exact"
}
]
}
}
Where should I find those request body templates? :(
Resources: https://learn.microsoft.com/en-us/rest/api/azure/devops/policy/configurations/create?view=azure-devops-rest-5.1&tabs=HTTP
Usually, when you could list or get the repo policy correctly, you could use the parameter configuration part of the returning result as the request body in creating the policy with post method.
rest api to list the branch policy.
GET https://dev.azure.com/{organization}/{project}/_apis/policy/configurations?api-version=5.1
with optional parameter
GET https://dev.azure.com/{organization}/{project}/_apis/policy/configurations?scope={scope}&policyType={policyType}&api-version=5.1
You could check the templates below for different configurations in Policy template examples.
Examples
Approval count policy
Build policy
Example policy
Git case enforcement policy
Git maximum blob size policy
Merge strategy policy
Work item policy
If you still don't know how to compose the request body, you could also share your scenario.
i finally made it, it was very hard and i dont understand why Microsoft has so bad documentation.... i had to made it by sending randoms request and look at the elements how the names are... so bad so much time spend...

How to add Keycloak realm role to group via REST API

I want to assign the realm role "TEST_ROLE_123" to a group, I am using
PUT /admin/realms/ataccamaone/groups/{group-id}
{
"realmRoles":["TEST_ROLE_123"]
}
I got group-id from /admin/realms/ataccamaone/groups/
However I get the response 204 No Content and in the Keycloak console I do not see the assignment.
I tried to reproduce your problem and find that PUT /admin/realms/ataccamaone/groups/{group-id} can only edit group name.
Inspect into "Network" tab of browser, I see it uses another URL to map roles to groups. And steps to do this via Admin REST API are:
Obtain PAT as described in https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_protection_whatis_obtain_pat section
Following steps use this PAT as Bearer token (in "Authorization" header). I guess you've already got this.
Call GET http://localhost:8080/auth/admin/realms/realm1/roles to get list of roles, including their name and id values.
Call GET http://localhost:8080/auth/admin/realms/realm1/groups to get list of groups, including their ids
Call POST http://localhost:8080/auth/admin/realms/realm1/groups/{group-id}/role-mappings/realm with following body:
[
{
"id": "9083cac3-4280-497d-b973-7713a5fb12b4", // role-id
"name": "secretary" // role-name
}
]
Call DELETE with URL and body same as step 4 to remove roles from group.
I've faced same issue and corrected it with using a GROUP, Basically I've added the preferred ROLE into the User Groups ROLE LIST and used that specific user group while creating the user via REST API.
Eg:- ADMIN_USER_GROUP -> INCLUDED ('ADMIN_ROLE')
Then User creation API Request should be like below,
{
"firstName": "Sergey",
"lastName": "Kargopolov",
"email": "test4#test.com",
"enabled": "true",
"credentials": [
{
"value": "123"
}
],
"groups": [
"ADMIN_USER_GROUP"
]
}

How do add an apitoken as part of a custom VSTS service endpoint datasource?

I'm am trying to implement a VSTS extension which adds a new service endpoint. Crucially, the authentication method for this service includes the API as part of the querystring.
I am using the "type": "ms.vss-endpoint.endpoint-auth-scheme-token" for AuthenticationScheme.
I've defined the dataSources like so:
"dataSources": [
{
"name": "TestConnection",
"endpointUrl": "{{endpoint.url}}projects?token={{endpoint.apitoken}}"
}
]
However, in performing a test to Verify Connection:
Failed to query service endpoint api: https://myserver.com/projects?token=.
endpoint.apitoken is always blank.
Is there a placeholder/replacement value that can be used to get access to this value or another way of achieving the same end result?
I've tried using different authentication schemes (such as 'none') and included a inputDescriptor to capture my apitoken, but I have the same result. There doesn't seem to be a way to reference these values?
No, it is not supported. This article may benefit you: Service endpoint authentication schemes

Security of cloudant query from OpenWhisk

I'm building an Angular SPA with a Cloudant data store on Bluemix.
Since the Bluemix implementation of OpenWhisk doesn't use VCAP services, I see 3 options to use OpenWhisk as my api provider for cloudant queries for my Angular app:
Follow the pattern of passing credentials as seen here: https://github.com/IBM-Bluemix/openwhisk-visionapp (very interesting approach btw)
Include the credentials as though I'm running locally as seen here: https://github.com/IBM-Bluemix/nodejs-cloudant/blob/master/app.js
Use the http API as seen here: https://docs.cloudant.com/api.html (which highlights the security problem passing credentials.
Since my service is not intended for publishing (it's intended for my own app) I'm thinking option 2 is my "least of all evils" choice. Am I missing something? My thinking is such that while fragile to changes it would be the most secure since credentials aren't passed in the open. The serverless infrastructure would have to be hacked...
Thanks in advance!
(lengthy) Update: (apologies in advance)
I've gotten a little farther along but still no answer - stuck in execution right now.
To clarify, my objective is for the app to flow from Angular Client -> OpenWhisk -> Cloudant.
In this simplest use case, I want to pass a startTime parameter and an endTime parameter, have OpenWhisk fetch all the records in that time range with all fields, and passing back selected fields. In my example, I have USGS earthquake data in a modified GeoJSON format.
Following information from the following articles below, I've concluded that I can invoke the wsk command line actions and use the bindings I've setup from within my Javascript function and therefore not pass my credentials to the database. This gives me a measure of security (still question the rest endpoint of my OpenWhisk action) but I figure once I get my sample running I think through that part of it.
My command line (that works):
wsk action invoke /my#orgname.com_mybluemixspace/mycfAppName/exec-query-find --blocking --result --param dbname perils --param query {\"selector\":{\"_id\":{\"$gt\":0},\"properties.time\":{\"$gt\":1484190609500,\"$lt\":1484190609700}}}
This successfully returns the following:
{
"docs": [
{
"_id": "eq1484190609589",
"_rev": "1-b4fe3de75d9c5efc0eb05df38f056a65",
"dbSaveTime": 1.484191201099e+12,
"fipsalpha": "AK",
"fipsnumer": "02",
"geometry": {
"coordinates": [
-149.3691,
62.5456,
0
],
"type": "Point"
},
"id": "ak15062242",
"properties": {
"alert": null,
"cdi": null,
"code": "15062242",
"detail": "http://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/ak15062242.geojson",
"dmin": null,
"felt": null,
"gap": null,
"ids": ",ak15062242,",
"mag": 1.4,
"magType": "ml",
"mmi": null,
"net": "ak",
"nst": null,
"place": "45km ENE of Talkeetna, Alaska",
"rms": 0.5,
"sig": 30,
"sources": ",ak,",
"status": "automatic",
"time": 1.484190609589e+12,
"title": "M 1.4 - 45km ENE of Talkeetna, Alaska",
"tsunami": 0,
"type": "earthquake",
"types": ",geoserve,origin,",
"tz": -540,
"updated": 1.484191127265e+12,
"url": "http://earthquake.usgs.gov/earthquakes/eventpage/ak15062242"
},
"type": "Feature"
}
]
}
The action I created in OpenWhisk (below) returns an Internal Server Error. I'm passing the input value as
{
"startTime": "1484161200000",
"endTime": "1484190000000"
}
Here's the code for my action:
`var openWhisk = require('openwhisk');
var ow = openWhisk({
api_key:'im really a host'
});
function main(params) {
return new Promise(function(resolve, reject) {
ow.actions.invoke({
actionName:'/my#orgname.com_mybluemixspace/mycfAppName/exec-query-find',
blocking:true,
parameters:{
dbname: 'perils',
query: {
"selector": {
"_id": {
"$gt": 0
},
"properties.time": {
"$gt": params.startTime,
"$lt": params.endTime
}
}
}
}
}).then(function(res) {
//get the raw result
var raw = res.response.result.rows;
//lets make a new one
var result = [];
raw.forEach(function(c) {
result.push({id:c.docs._id, time:c.docs.properties.time, title:c.docs.properties.title});
});
resolve({result:result});
});
});
}`
Here are the links to my research:
http://infrastructuredevops.com/08-17-2016/news-openwhisk-uniq.html
Useful because of the use of the exec-query-find and selector syntax usage but also cool for the update function I need to build for populating my data!
https://www.raymondcamden.com/2016/12/23/going-serverless-with-openwhisk
The article referenced by #csantanapr
Am I overlooking something?
Thanks!
I'm assuming what you are trying to do is to access your Cloudant DB directly from your angular client side code from the Browser.
If you don't need any business logic, or you can get away by using Cloudant features (design docs, views, map, reduce, etc..) and you are generating Cloudant API keys with certain access (i.e. write vs. read), then you don't need a server or serveless middlewear/tier.
But now let's get real, most people need that tier, and if you are looking a OpenWhisk, then you are in good luck this is very easy to do.
OpenWhisk on Bluemix support VCAP service credentials, but in a different way.
Let's name you have a Bluemix Org carlos#example.com and space dev that would translate to OpenWhisk namespace carlos#example.com_dev
If you add a Cloudant service under the space dev in Bluemix, this will generate service key credentials for this Cloudant Account. This credentials give you super power access meaning you are admin.
If you want to use this Cloudant credentials in OpenWhisk, you can use the automatic binding generated with the cloudant package.
To do this using the OpenWhisk CLI run wsk package refresh this will pull the Cloudant credentials and create you a new package with the credentials binded as default parameter for all the cloudant actions under that package. This is modified version of #1 above
Another alternative is to bind the credentials manually to a package or an action as default parameters, this makes sense when you don't want to use the super power admin credentials, and you generated a Cloudant API key for a specific database. This is option #1 above.
I would not recommend to put the credentials in source code #2
For option #3, what's insecure is to pass your credentials as part of the URL like https://username:password#user.cloudant.com, but passing the username and password in the Authorization header over https is secured.
This is because even if you are using secure transport https everything in the URI/URL is not encrypted anyone can see that value, but passing secrets in body or header is standard practice as this is transfer after secure connection is established.
Then you create actions that use the credentials as parameters in your OpenWhisk actions to build your business logic for your backend.
Then how to do you access this backend from the Browser, well OpenWhisk has a API Gateway feature in experimental that allows your to expose your actions as public APIs with CORS enable.
Only a url is expose, your credentials as default parameters are never expose.
If you want to see an example on check out Raymond Camden Blog posts where he show Ionic/Angular App accessing his Cloudant Database of Cats
https://www.raymondcamden.com/2016/12/23/going-serverless-with-openwhisk

DocuSign: setting user permissions using REST APIs

For creating a group, a user and assigning the user to that group, I referred this link Add permission profile through API.
Using REST APIs I am able to do that but permission for user is not getting set.
When I check in DocuSign, group is having correct permission set but same is not set for a user. Please let me know if I am missing anything.
Additional Information: This is the request I am sending
{
"newUsers":[{
"email":"'.$email.'",
"userName":"'.$userName.'",
"password":"'.$password.'",
"groupList": [{
"groupId": "'.$groupId.'",
"groupName": "'.$groupName.'",
"permissionProfileId": "'.$permissionId.'"
}]
}]
}
Also, when a user is added to a group, permissions set at group level will be applied to the users. Is there something missing?
When you create a permission profile you use this endpoint:
POST {vx}/accounts/{accountid}/permission_profiles
the response body for that endpoint should contain this info ( I omitted some details from the response)
{
"permissionProfileId": "sample string 1",
"permissionProfileName": "sample string 2",
...
}
Once you have the permissionProfileId and permissionProfileName you should be able to assign that permission profile to a user using this endpoint:
PUT {vx}/accounts/{accountid}/users/{userid}
and using the permissionProfileId and permissionProfileName in your request (I used dummy values here):
{
"permissionProfileId": "12345",
"permissionProfileName": "SomeName"
}
I hope that helps!
-Yadriel