{"id":20291277,"url":"https://github.com/arsenvlad/azure-storage-queue-rbac","last_synced_at":"2025-10-13T06:18:21.525Z","repository":{"id":97982165,"uuid":"144229793","full_name":"arsenvlad/azure-storage-queue-rbac","owner":"arsenvlad","description":"Simple example showing how to read and delete messages from Azure Storage queue using multi-tenanted Azure AD application credential","archived":false,"fork":false,"pushed_at":"2018-08-10T03:05:54.000Z","size":3,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-04T04:44:27.157Z","etag":null,"topics":["azure","azure-ad","azure-queue"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arsenvlad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-10T03:04:13.000Z","updated_at":"2018-08-10T15:49:44.000Z","dependencies_parsed_at":"2023-03-15T03:16:54.246Z","dependency_job_id":null,"html_url":"https://github.com/arsenvlad/azure-storage-queue-rbac","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/arsenvlad/azure-storage-queue-rbac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsenvlad%2Fazure-storage-queue-rbac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsenvlad%2Fazure-storage-queue-rbac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsenvlad%2Fazure-storage-queue-rbac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsenvlad%2Fazure-storage-queue-rbac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arsenvlad","download_url":"https://codeload.github.com/arsenvlad/azure-storage-queue-rbac/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsenvlad%2Fazure-storage-queue-rbac/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013959,"owners_count":26085429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-ad","azure-queue"],"created_at":"2024-11-14T15:11:28.981Z","updated_at":"2025-10-13T06:18:21.489Z","avatar_url":"https://github.com/arsenvlad.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure Storage Queue RBAC across Azure AD tenants\r\n\r\nDocument describing Azure Storage Authentication with Azure AD (Preview)\r\nhttps://docs.microsoft.com/en-us/rest/api/storageservices/authenticate-with-azure-active-directory\r\n\r\nSelect ISV subscription\r\n```\r\naz account list\r\naz account set --subscription \"isv\"\r\n```\r\n\r\nCreate multi-tenanted Azure AD application in the ISV tenant using https://portal.azure.com/ with a password key and required resource access to Azure AD\r\n```\r\naz ad app create --display-name avmultitenant2 --available-to-other-tenants true --homepage http://localhost/avmultitenant2 --reply-urls http://localhost/avmultitenant2 --identifier-uris https://this-domain-must-match-your-tenant-url.com/avmultitenant2 --key-type Password --password PutSecureKeyValueHere123 --required-resource-accesses app-required-resource-accesses.json\r\n```\r\n\r\nAdmin consent customer subscription to the multi-tenanted application created above by visting URL like below in a browser\r\n```\r\nhttps://login.microsoftonline.com/{customer-tenant}/adminconsent?client_id={isv-application-id}\u0026state={any-state-to-pass}\u0026redirect_uri={isv-application-return-url}\r\n```\r\n\r\nSwitch to the cutomer subscription and tenant\r\n```\r\naz account set --subscription \"customer\"\r\n```\r\n\r\nList existing custom roles\r\n```\r\naz role definition list --custom-role-only true\r\n```\r\n\r\nCreate custom role for Storage Queue Processor (read/delete) after setting proper subscription id in the .json file definition for the role\r\n```\r\naz role definition create --role-definition custom-role-queue-processor.json\r\n```\r\n\r\nCreate storage account and queue in the customer subscription (if you don't have them yet)\r\n```\r\naz group create --name avegs1 --location eastus2\r\naz storage account create --resource-group avegs1 --sku Standard_LRS --kind StorageV2 --name avegs1\r\naz storage queue create --account-name avegs1 --name queue1\r\nexport storageAccountResourceId=$(az storage account show --resource-group avegs1 --name avegs1 --query id -o tsv)\r\nexport queueResourceId=$storageAccountResourceId/queueServices/default/queue1\r\nexport ak=$(az storage account keys list --resource-group avegs1 --account-name avegs1 --query \"[0].value\" -o tsv)\r\n```\r\n\r\nGrant newly created \"Storage Queue Processor Custom Role\" definition to the multi-tenanted ISV application Service Principal in customer's subscription to the queue\r\n(Azure CLI example below creates the assignment at the scope of storage account because az cli does not yet have version 2018-03-01-preview for assigned roles to queueServices. For now, use https://portal.azure.com or an ARM template to create the role assignment at queue scope)\r\n```\r\naz ad list sp --display-name avmultitenant2\r\naz role assignment create --role \"Storage Queue Processor Custom Role\" --assignee {service-principal-id} --scope \"$storageAccountResourceId\"\r\n```\r\n\r\nISV can now obtain access_token using their application's client_id and client_secret and customer's tenant\r\n```\r\ncurl -X POST 'https://login.microsoftonline.com/{customer-tenant}/oauth2/token' -d 'grant_type=client_credentials\u0026resource=https://storage.azure.com/\u0026client_id={isv-application-service-principal-id}\u0026client_secret={isv-application-secret}'\r\n```\r\n\r\nSet access_token environment variable to make it easier to make curl calls shown below\r\n```\r\nexport access_token=\"{value-returned-by-login-oauth2-token}\"\r\n```\r\n\r\nUse the obtained access_token to peek at messages in the queue\r\n```\r\ncurl -X GET -H 'x-ms-version: 2017-11-09' -H \"Authorization: Bearer $access_token\" https://avegs1.queue.core.windows.net/queue1/messages?peekonly=true\r\n```\r\n\r\nTrying adding a new message to queue. It should fail because the custom role  created allows only read and delete but not write\r\n```\r\ncurl -X POST -H 'x-ms-version: 2017-11-09' -H \"Authorization: Bearer $access_token\" https://avegs1.queue.core.windows.net/queue1/messages -d '\u003cQueueMessage\u003e\u003cMessageText\u003eSGVsbG8gV29ybGQh\u003c/MessageText\u003e\u003c/QueueMessage\u003e'\r\n```\r\n\r\nError returned will be similar to\r\n```\r\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\r\n\u003cError\u003e\u003cCode\u003eAuthorizationPermissionMismatch\u003c/Code\u003e\r\n\u003cMessage\u003eThis request is not authorized to perform this operation using this permission.\r\nRequestId:eacd4d79-e003-0031-304e-30da8d000000\r\nTime:2018-08-10T02:03:34.2897261Z\u003c/Message\u003e\u003c/Error\u003e\r\n```\r\n\r\nGet messages from the queue including popreceipt value\r\n```\r\ncurl -X GET -H 'x-ms-version: 2017-11-09' -H \"Authorization: Bearer $access_token\" https://avegs1.queue.core.windows.net/queue1/messages\r\n```\r\n\r\nIf there are messages in the queue, try to delete one by passing the message id and corresponding popreceipt value obtained from get messages\r\n```\r\ncurl -X DELETE -H 'x-ms-version: 2017-11-09' -H \"Authorization: Bearer $access_token\" https://avegs1.queue.core.windows.net/queue1/messages/{messageid}?popreceipt={popreceipt-string-from-get-messages}\r\n```\r\n\r\nCURL calls above show how to interact with the queue using raw REST API. Azure Storage Java SDK (and others) provide similar functionality and support OAuth tokens as of 2018.05.22 Version 7.1.0\r\n\r\n* Example Azure Storage Java SDK code showing how to obtain OAuth token using client credential\r\nhttps://github.com/Azure/azure-storage-java/blob/07fba08e00d3fa29161b8fd9ad0042c5f932cd78/microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestHelper.java#L82\r\n\r\n* Example Azure Storage Java SDK code showing how to create StorageCredentialsToken from the OAuth token:\r\nhttps://github.com/Azure/azure-storage-java/blob/4195c3286c508f93d446b600d9ccd54e2eb9deed/microsoft-azure-storage-test/src/com/microsoft/azure/storage/OAuthTests.java#L61\r\n\r\n* Example Azure Storage Java SDK code for interacting with Azure Queue\r\nhttps://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/queue/gettingstarted/QueueBasics.java\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsenvlad%2Fazure-storage-queue-rbac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farsenvlad%2Fazure-storage-queue-rbac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsenvlad%2Fazure-storage-queue-rbac/lists"}