{"id":29001708,"url":"https://github.com/erwinkramer/synapse-dep-data-flows-func","last_synced_at":"2026-02-12T13:39:59.212Z","repository":{"id":298095394,"uuid":"998849302","full_name":"erwinkramer/synapse-dep-data-flows-func","owner":"erwinkramer","description":"Securely call Azure Functions with Synapse data flows.","archived":false,"fork":false,"pushed_at":"2025-06-09T15:25:38.000Z","size":246,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T03:40:30.448Z","etag":null,"topics":["azure-functions","azure-synapse","data-exfiltration","entra-id","synapse","synapse-dataset"],"latest_commit_sha":null,"homepage":"https://guanchen.nl","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erwinkramer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2025-06-09T10:54:18.000Z","updated_at":"2025-09-19T08:28:14.000Z","dependencies_parsed_at":"2025-06-09T11:45:57.672Z","dependency_job_id":"866d044c-13b5-4a83-9fd9-14e614d69562","html_url":"https://github.com/erwinkramer/synapse-dep-data-flows-func","commit_stats":null,"previous_names":["erwinkramer/synapse-dep-data-flows-func"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erwinkramer/synapse-dep-data-flows-func","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwinkramer%2Fsynapse-dep-data-flows-func","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwinkramer%2Fsynapse-dep-data-flows-func/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwinkramer%2Fsynapse-dep-data-flows-func/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwinkramer%2Fsynapse-dep-data-flows-func/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erwinkramer","download_url":"https://codeload.github.com/erwinkramer/synapse-dep-data-flows-func/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erwinkramer%2Fsynapse-dep-data-flows-func/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29367434,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T08:51:36.827Z","status":"ssl_error","status_checked_at":"2026-02-12T08:51:26.849Z","response_time":55,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-functions","azure-synapse","data-exfiltration","entra-id","synapse","synapse-dataset"],"created_at":"2025-06-25T09:11:42.977Z","updated_at":"2026-02-12T13:39:59.197Z","avatar_url":"https://github.com/erwinkramer.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Synapse DEP-workspace data flows with secure Azure Functions 🌊\n\n[![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa]\n![GitHub commit activity](https://img.shields.io/github/commit-activity/m/erwinkramer/synapse-dep-data-flows-func)\n\n[Data exfiltration protection for Azure Synapse Analytics workspaces (DEP)](https://docs.azure.cn/en-us/synapse-analytics/security/workspace-data-exfiltration-protection) blocks external calls, even when trying to get tokens with custom audience from your Entra ID tenant. This sample proves that it is possible to do some flexible calls to an Entra ID-secured Function App in a DEP-enabled workspace, with custom token audience, without the need of pipelines. \n\n## Reproduction steps\n\n1. Create an Entra ID app registration. In this sample, the `Application ID URI` is `api://bank-nl`:\n![alt text](.images/app.png)\n\n1. Create a Function App. In this sample, the app has the domain `func-otel.azurewebsites.net`. For demo purposes, add the following identity configuration to your Function App. The `Allowed identities` value is the `Object ID` of the system assigned identity of your Synapse resource in your tenant:\n\n   ![alt text](.images/functionapp.png)\n\n1. Create a `REST` linked service, pointing to your Function App (via the `Base URL`), and the Entra ID app registration (via the `Microsoft Entra ID resource`):\n\n   ![alt text](.images/linked-service.png)\n\n1. Create a managed private endpoint, pointing to the Function App. The `fqdns` in the managed private endpoint must match with the `REST` linked service `Base URL` domain part:\n\n   ![alt text](.images/mpe.png)\n\n1. Create a [data flow](https://learn.microsoft.com/en-us/azure/synapse-analytics/concepts-data-flow-overview) with a [dataset](https://learn.microsoft.com/en-us/azure/data-factory/concepts-datasets-linked-services?tabs=data-factory) based on a `REST` store, and select the `REST` linked service you created earlier:\n\n   ![alt text](.images/dataflow.png)\n\n1. Finally, test your connection, this will actually use your system assigned identity and will attempt to call via your linked service:\n\n   ![alt text](.images/test.png)\n\n## Why does this work? \n\nThere are 2 points to notice:\n\n1. Even though we're not using a Function App dataset, simply because that doesn't exist, it still matches your `REST` configuration with the managed private endpoint connection of your Function App. DEP will allow all connections that have managed private endpoints.\n1. Because authentication is in context of the linked service, DEP will allow that.\n\n## What about notebooks?\n\nAttempting to get an access token or using the linked service in a Synapse notebook with DEP enabled, for Function Apps, will yield: `Linked Service Type 'RestService' not supported`  (for `REST` type) or `Linked Service Type 'AzureFunction' not supported` (for `Function App` type). Some will work, such as a Azure ML workspace linked service, as explained here https://github.com/Azure/azure-sdk-for-python/issues/35452#issuecomment-2343629054, but in this scenario it's not useful. For a list of supported types, see [Linked service connections supported from the Spark runtime](https://learn.microsoft.com/en-us/azure/synapse-analytics/spark/apache-spark-secure-credentials-with-tokenlibrary?pivots=programming-language-python#linked-service-connections-supported-from-the-spark-runtime).\n\nDisable DEP on the workspace and make manual REST calls in the notebook as an alternative. Leverage the [Requests](https://pypi.org/project/requests/) library, for example.\n\n## License\n\nThis work is licensed under a\n[Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License][cc-by-nc-sa].\n\n[![CC BY-NC-SA 4.0][cc-by-nc-sa-image]][cc-by-nc-sa]\n\n[cc-by-nc-sa]: http://creativecommons.org/licenses/by-nc-sa/4.0/\n[cc-by-nc-sa-image]: https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png\n[cc-by-nc-sa-shield]: https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferwinkramer%2Fsynapse-dep-data-flows-func","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferwinkramer%2Fsynapse-dep-data-flows-func","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferwinkramer%2Fsynapse-dep-data-flows-func/lists"}