{"id":6414,"date":"2024-08-27T22:20:12","date_gmt":"2024-08-27T21:20:12","guid":{"rendered":"https:\/\/andreas-wolter.com\/?p=6414"},"modified":"2024-09-07T21:25:16","modified_gmt":"2024-09-07T20:25:16","slug":"7wishes-access-control-sqlserver-azuresql-security","status":"publish","type":"post","link":"https:\/\/andreas-wolter.com\/en\/7wishes-access-control-sqlserver-azuresql-security\/","title":{"rendered":"My 7 wishes for access control in SQL Server and Azure SQL security"},"content":{"rendered":"\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-m0cxh8ps-94e8226d297e664730f08804be1c56d9\">\n#top .av-special-heading.av-m0cxh8ps-94e8226d297e664730f08804be1c56d9{\npadding-bottom:10px;\n}\nbody .av-special-heading.av-m0cxh8ps-94e8226d297e664730f08804be1c56d9 .av-special-heading-tag .heading-char{\nfont-size:25px;\n}\n.av-special-heading.av-m0cxh8ps-94e8226d297e664730f08804be1c56d9 .av-subheading{\nfont-size:15px;\n}\n<\/style>\n<div  class='av-special-heading av-m0cxh8ps-94e8226d297e664730f08804be1c56d9 av-special-heading-h3 blockquote modern-quote  avia-builder-el-0  el_before_av_textblock  avia-builder-el-first '><h3 class='av-special-heading-tag'  itemprop=\"headline\"  >My 7 wishes for access control in SQL Server and Azure SQL security<\/h3><div class=\"special-heading-border\"><div class=\"special-heading-inner-border\"><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-m0cxgkjy-c935304b4106b45214698f40e83a9894 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>As I have indicated in my farewell post after I resigned from the Azure SQL Security org, there are some features and functionality-gaps which I would have loved to see being prioritized.<\/p>\n<p>And as I am still feeling very attached to this work, I wanted to write down my latest thoughts on Access Control in SQL Server and Azure SQL.<\/p>\n<p>Maybe some of it will even get picked up by a successor in Access Control for SQL Server and Azure SQL.<\/p>\n<p>Content:<\/p>\n<ol>\n<li>Make the effect of ownership-chains in SQL optional<\/li>\n<li>Limit or block the use of SA<\/li>\n<li>Complete the RBAC coverage for SQL using Azure IAM RBAC<\/li>\n<li>Continue the improvements for PoLP compliance for SQL \u2013 remove sysadmin and db_owner requirements<\/li>\n<li>Modernize SQL Agent security<\/li>\n<li>Implement Attribute Based Access Control for SQL based on MAC-principles<\/li>\n<li>Better Entra ID experience to allow testing and similar<\/li>\n<\/ol>\n<p>Alright, let\u2019s get to the details:<\/p>\n<p>Please pretty please\u2026 \ud83d\ude42<\/p>\n<h1><a name=\"_Toc175658807\"><\/a>1) Make the effect of ownership-chains in SQL optional<\/h1>\n<h2><a name=\"_Toc175658808\"><\/a>Background<\/h2>\n<p>This is about a specific behavior of the SQL permission system, which, in a nutshell, leads to that when an object is called from another module or view, permissions will not be checked if the owners of the two objects in this \u201cchain\u201d are the same.<br \/>\nWhile this is super helpful and makes authorization much simpler to set up, it also introduces a <strong>risk of unforeseen Data Exfiltration attacks<\/strong>. As I have been presenting this subject to hundreds of people over the last 2 decades, I can tell from experience that less than 5% of those working with SQL understand this in all detail and consequences.<\/p>\n<p>With the introduction of external access control via Microsoft Purview Data access policies this issue becomes visible from a new angle. Even such a system, designed for centrally controlling access to SQL objects via policies and its attribute based denies can be circumvented using ownership-chaining!<\/p>\n<h2><a name=\"_Toc175658809\"><\/a>Feature request<\/h2>\n<p>My <strong>proposed solution<\/strong> is to make this ownership chaining based behavior explicit so it can be disabled on a per-user and per database or even better per schema-level. Instead of just assuming that no permissions need to be checked if all owners in the chain are the same, it will require the user to have a new permission, something like <strong>INHERIT_ PERMISSIONS_VIA_CHAIN<\/strong>. Without that, no permissions will be inherited from the ownership-chains for that user.<\/p>\n<p>The following diagram depicts the behaviors possible with that change:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6415 size-full\" src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal.jpg\" alt=\"Ownership Chaining Explicit Permission proposal\" width=\"954\" height=\"361\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal.jpg 954w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-300x114.jpg 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-768x291.jpg 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-705x267.jpg 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-845x321.jpg 845w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-450x170.jpg 450w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_Ownership_Chaining_Explicit_Permission_proposal-600x227.jpg 600w\" sizes=\"auto, (max-width: 954px) 100vw, 954px\" \/><\/p>\n<p>From well-informed sources I know that there is a working prototype \ud83d\ude09<\/p>\n<h1><a name=\"_Toc175658810\"><\/a>2) Limit or block the use of SA<\/h1>\n<p>The built-in sa is still the most attacked account in SQL Server for obvious reasons (high value target, known account name and sid).<\/p>\n<p>While it will need to keep working for internal processes until a big system overhaul, it should be possible to at least <strong>block or limit any interactive use of sa<\/strong> to block this attack vector.<\/p>\n<p>Note: This will also require to improve security for SQL Server Agent (another topic on this list to make SQL Server comply with PoLP (Principle of Least Privilege) and replication.<\/p>\n<h1><a name=\"_Toc175658811\"><\/a>3) Complete the RBAC coverage for SQL using Azure IAM RBAC<\/h1>\n<h2><a name=\"_Toc175658812\"><\/a>Background<\/h2>\n<p>My biggest project was to develop a way for SQL to understand and enforce access control (both Authentication and Authorization) at scale, controlled from an external point: the policy provider.<\/p>\n<p>While integrating with Azure IAM RBAC (<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/role-based-access-control\/overview\" target=\"_blank\" rel=\"noopener\">What is Azure role-based access control<\/a>) would have been the logical choice, for manpower reasons we based the architecture on Microsoft Purview. This made it possible to extend the concept to a form of Attribute Based Access Control (ABAC) as well, using the classifiers from Purview. (I will get to that in a later point again)<\/p>\n<p>We managed to release a comprehensive and self-sufficient set of permissions, which cover two typical roles for SQL: Performance Monitoring &#038; Analysis as well as Security Auditing. Those are now available under the name DevOps policies within Purview (more here: <a href=\"https:\/\/learn.microsoft.com\/en-us\/purview\/how-to-policies-devops-authoring-generic\" target=\"_blank\" rel=\"noopener\">Create, list, update, and delete Microsoft Purview DevOps policies<\/a> ).<\/p>\n<p>However, there has been no progress since then, which makes is hard to justify for anyone to start using this policy infrastructure.<\/p>\n<h2><a name=\"_Toc175658813\"><\/a>Feature request<\/h2>\n<p>Please craft the next complete set of roles, for example \u201cend-users\u201d to allow the use of the most typical database objects (tables, views, functions, stored procedures) with read and write, respectively execute-access.<br \/>\nI would even hope that this can be continued under the Azure IAM RBAC model, which would open this space for <u>all customers,<\/u> not requiring Microsoft Purview, which as I have heard from all sides, is a big overhead and blocker for using the RBAC roles.<\/p>\n<h1><a name=\"_Toc175658814\"><\/a>4) Continue the improvements for PoLP compliance for SQL \u2013 remove sysadmin and db_owner requirements<\/h1>\n<h2><a name=\"_Toc175658815\"><\/a>Background<\/h2>\n<p>While I was working in the SQL Data security team, unfortunately there was never a dedicated budget for reworking the SQL permission model. However, I managed to justify the introduction of about 50 new granular permissions with the work on the RBAC action-system: Since all these new actions by design had to be more granular than SQL was at that time, and the code for the permission checks had to be adjusted anyway, we could justify the additions to the SQL permission with exactly the fact that we had to change the specific permission checks in the engine code anyway.<br \/>\nSo instead of waiting for a later time for a budget for SQL permission granularity improvements, we did it in one go with very little overhead.<\/p>\n<p>Here is the blog post explaining the new permissions:<br \/>\n<a href=\"https:\/\/techcommunity.microsoft.com\/t5\/sql-server-blog\/new-granular-permissions-for-sql-server-2022-and-azure-sql-to\/ba-p\/3607507\" target=\"_blank\" rel=\"noopener\">New granular permissions for SQL Server 2022 and Azure SQL to improve adherence with PoLP<\/a> and here some more details on the work behind:<br \/>\n<a href=\"https:\/\/techcommunity.microsoft.com\/t5\/azure-sql-blog\/revamped-sql-permission-system-for-principle-of-least-privilege\/ba-p\/3639399\" target=\"_blank\" rel=\"noopener\">Revamped SQL Permission system for Principle of Least Privilege and external policies \u2013 internals<\/a><\/p>\n<h2><a name=\"_Toc175658816\"><\/a>Feature request<\/h2>\n<p>My wish is that the work on removing sysadmin\/db_owner requirements continue. There is too much to do to list all the details, but I can probably safely say that finishing the work on <strong>DBCC-command permissions<\/strong> should be on top of this list. Finalizing the new permission requirements was one of the last tasks that I finished before I left, so it should b easy to pick that up even without a PM successor in place.<\/p>\n<p>The next permission changes then should be anything around security functionalities such as creating accounts, roles and managing permissions.<br \/>\nFor example, it should be possible to differentiate between someone who creates a database role and someone who can grant permissions to a role. And both should be possible without at the same time being able to create accounts.<\/p>\n<h1><a name=\"_Toc175658817\"><\/a>5) Modernize SQL Agent security<\/h1>\n<p>I don\u2019t think I will offend anyone still working on SQL Server if I say what every consultant knows: The SQL Agent job system security has been a thorn in any security concept for SQL for the last 2 decades by now. It was developed in a time where PoLP and SoD (Separation of Duties) where merely exotic terms that seemed unnecessary for SQL Server management functionalities.<\/p>\n<p>To allow SQL Server management with lower permissions, we need a way to <strong>allow groups of users to create and edit certain jobs<\/strong> instead of being forced to have every job owned by sa because of the current limitations. The current system is just not built for real-world requirements where multiple non-admins need to change a job.<\/p>\n<p>Given the age of the SQL Agent job system code (much older than most engineers who still work in the SQL org), I do think it would be easier to rebuild something modern from scratch. &#8211; But by that I mean something that can be used without forcing customers to connect to the cloud to download jobs. (just saying \ud83d\ude42<\/p>\n<h1><a name=\"_Toc175658818\"><\/a>6) Implement Attribute Based Access Control for SQL based on MAC-principles<\/h1>\n<h2><a name=\"_Toc175658819\"><\/a>Background<\/h2>\n<p>With SQL Server 2012 Data Classification (<a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/security\/sql-data-discovery-and-classification?view=sql-server-ver16&#038;tabs=t-sql\" target=\"_blank\" rel=\"noopener\">SQL Data Discovery and Classification<\/a> ) was introduced.<\/p>\n<p>This functionality allows labeling columns with free text labels which then also show up in Audit records.<br \/>\nWhile working on the Purview Integration for RBAC policies, a team working in parallel also implemented a way to use Microsoft Purview Labels as the source for the MIP labels (using the infrastructure that we implemented for RBAC) and in 2024 the Purview team published the Preview for what is now called \u201cinformation protection policies\u201d: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/azure-sql\/database\/data-discovery-and-classification-overview?view=azuresql#enabling-access-control-for-sensitive-data-using-microsoft-purview-information-protection-policies-public-preview\" target=\"_blank\" rel=\"noopener\">Microsoft Purview Information Protection policy<\/a>)<\/p>\n<p>Those policies can use labels on columns in Azure SQL database which are stored in the Purview catalog to make Deny-only decisions for queries in SQL. In other words, it is possible to specify that when a column is labelled as \u201csensitive\u201d that a policy is implemented that prohibits certain users to see the content. If such user writes a query that touches the \u201csensitive\u201d column, the query will fail with a permission error.<\/p>\n<p>However, this kind of policy can be circumvented by using ownership-chains in SQL. (See my number 1 wish in this list). In my eyes, this severely weakens the concept of a central access control policy and should not be the default-behavior for a proper MAC- or ABAC-system in my opinion. (MAC = Mandatory Access Control, ABAC: Attribute Based Access Control)<\/p>\n<p>Secondly, customers choosing to use these information protection policies currently will see their queries failing with a permission error on each denied column like so:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6417 size-full\" src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_PermissionDeniedPurview_MSFT.png\" alt=\"\u201cpermission denied\u201d error in SQL\" width=\"646\" height=\"222\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_PermissionDeniedPurview_MSFT.png 646w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_PermissionDeniedPurview_MSFT-300x103.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_PermissionDeniedPurview_MSFT-450x155.png 450w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2024\/08\/202408_PermissionDeniedPurview_MSFT-600x206.png 600w\" sizes=\"auto, (max-width: 646px) 100vw, 646px\" \/><\/p>\n<p>Failing queries like that breaks applications unnecessarily. One should consider that this is a policy that evaluates an attribute on a column and not a permission. There is a fine distinction that can be made: permissions are a static concept. You either have it or you don\u2019t. An attribute on the other hand is not granted\/given. While some attributes may <u>behave<\/u> statically, in terms of evaluation, they can be assumed dynamic. Not because a policy or a permission is changed, but because the attribute itself can be changed (by a process that is separate from policy authoring itself).<\/p>\n<p>Therefore, it is much more useful if the system simply redacts the values that are to be blocked instead of failing the whole query.<\/p>\n<h2><a name=\"_Toc175658820\"><\/a>Feature request<\/h2>\n<p>My wish would be to<strong> create a proper ABAC system that (A) does not fail queries but instead <em>redacts<\/em> columns which are not allowed to be seen<\/strong>, so that the query still runs but omits data for these columns and <strong>(B)<\/strong> <strong>ensure that this cannot be otherwise circumvented via the effect of ownership-chaining<\/strong>.<br \/>\nBy redacting the data, this system could be used without risk of breaking applications.<br \/>\nAnd why it\u2019s important to block circumventing classification-based access policies I don\u2019t think requires further explanation :-).<\/p>\n<p>Further thoughts:<\/p>\n<p>It would be good to consider fundamental principles such as the Bell-La Padula model to further tighten this security model to limit which labels which persona can set and change in which direction (which requires a hierarchical relationship between classification-labels to exist in first place).<br \/>\nLastly, I would hope that at last some of this functionality will be usable in SQL without using Microsoft Purview at all, including on-premises.<\/p>\n<h1><a name=\"_Toc175658821\"><\/a>7) Better Entra ID experience to allow testing and similar<\/h1>\n<p>Entra ID and Windows Active Directory provide much stronger security guarantees that SQL Server\u2019s own Authentication mechanism, \u201cSQL Authentication\u201d. Yet, even professionals like me still use SQL Auth extensively, both for testing and in demos. Why is that?<br \/>\nThe main reason that for testing and demos professionals like me need to be able to quickly use some dummy account. This is even true for Engineers at Microsoft. This is a real world, practical issue.<\/p>\n<p>However, till today there is no solution to assist with this fundamental requirement. Any account has to be properly requested from an Active Directory\/Entra ID Administrator, which can go through many hoops.<\/p>\n<p>What I am wishing for is that someone come up with a way to <strong>allow non-Administrators to quickly spawn up new accounts for limited use<\/strong>. Of course, these accounts must have no privileges at all, and it must be easy to track who the actual \u201cowner\u201d\/creator is, so that nobody can just use this to hide his or her identity.<br \/>\nAdmittedly this is something the SQL data team cannot built alone. But given that this is such a common reason, I thought I would mention it here.<\/p>\n<h1><a name=\"_Toc175658822\"><\/a>Conclusion<\/h1>\n<p>If you read until here, you must be really interested in SQL Security. Maybe you even want to work in the SQL Security team?<\/p>\n<p>There are other wishes I would have for SQL security, but this post is about Access Control related functionalities, which is the space I was working in.<\/p>\n<p>Thank you for reading and let me know your thoughts<\/p>\n<p>Andreas<\/p>\n<\/div><\/section>\r\n\r\n<div  class='hr av-baku8u-c77559299fb7cb036a9bcb2d27e7c839 hr-default  avia-builder-el-2  el_after_av_textblock  el_before_av_one_full '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-8qrdby-716ba84fac604695b00357bfaeecd241\">\n#top .flex_column.av-8qrdby-716ba84fac604695b00357bfaeecd241{\nmargin-top:40px;\nmargin-bottom:40px;\n}\n.flex_column.av-8qrdby-716ba84fac604695b00357bfaeecd241{\nborder-radius:0px 0px 0px 0px;\npadding:0px 0px 0px 0px;\n}\n.responsive #top #wrap_all .flex_column.av-8qrdby-716ba84fac604695b00357bfaeecd241{\nmargin-top:40px;\nmargin-bottom:40px;\n}\n<\/style>\n<div  class='flex_column av-8qrdby-716ba84fac604695b00357bfaeecd241 av_one_full  avia-builder-el-3  el_after_av_hr  el_before_av_social_share  first flex_column_div av-zero-column-padding  '     ><section  class='av_textblock_section av-sfssu-f7aca6dd816d63048075328792dddaf6 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><div><\/div>\n<div><\/div>\n<\/div><\/section><\/div>\r\n\r\n<div  class='av-social-sharing-box av-5n5vpa-c94cb34755a56dc3b3e18e46071a5152 av-social-sharing-box-default  avia-builder-el-5  el_after_av_one_full  el_before_av_hr  av-social-sharing-box-fullwidth'><div class=\"av-share-box\"><h5 class='av-share-link-description av-no-toc '>Eintrag teilen<\/h5><ul class=\"av-share-box-list noLightbox\"><li class='av-share-link av-social-link-facebook' ><a target=\"_blank\" aria-label=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https:\/\/andreas-wolter.com\/en\/7wishes-access-control-sqlserver-azuresql-security\/&#038;t=My%207%20wishes%20for%20access%20control%20in%20SQL%20Server%20and%20Azure%20SQL%20security\" aria-hidden=\"false\" data-av_icon=\"\ue8f3\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Facebook\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Facebook<\/span><\/a><\/li><li class='av-share-link av-social-link-twitter' ><a target=\"_blank\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=My%207%20wishes%20for%20access%20control%20in%20SQL%20Server%20and%20Azure%20SQL%20security&#038;url=https:\/\/andreas-wolter.com\/en\/?p=6414\" aria-hidden=\"false\" data-av_icon=\"\ue8f1\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Twitter\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Twitter<\/span><\/a><\/li><li class='av-share-link av-social-link-linkedin' ><a target=\"_blank\" aria-label=\"Share on LinkedIn\" href=\"https:\/\/linkedin.com\/shareArticle?mini=true&#038;title=My%207%20wishes%20for%20access%20control%20in%20SQL%20Server%20and%20Azure%20SQL%20security&#038;url=https:\/\/andreas-wolter.com\/en\/7wishes-access-control-sqlserver-azuresql-security\/\" aria-hidden=\"false\" data-av_icon=\"\ue8fc\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on LinkedIn\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on LinkedIn<\/span><\/a><\/li><\/ul><\/div><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-4ofg9q-c2108540b480aba02923089240a3a176\">\n#top .hr.hr-invisible.av-4ofg9q-c2108540b480aba02923089240a3a176{\nheight:50px;\n}\n<\/style>\n<div  class='hr av-4ofg9q-c2108540b480aba02923089240a3a176 hr-invisible  avia-builder-el-6  el_after_av_social_share  el_before_av_comments_list '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n<div  class='av-buildercomment av-284ftq-f5a1564cd6b8ffad6ce835e2d40de4b7  av-blog-meta-author-disabled av-blog-meta-html-info-disabled'><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":4,"featured_media":6415,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[132,57],"tags":[27],"class_list":["post-6414","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-miscellaneous","category-security-en","tag-security-en"],"_links":{"self":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6414","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/comments?post=6414"}],"version-history":[{"count":45,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6414\/revisions"}],"predecessor-version":[{"id":6533,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6414\/revisions\/6533"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media\/6415"}],"wp:attachment":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media?parent=6414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/categories?post=6414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/tags?post=6414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}