{"id":6092,"date":"2021-02-01T17:10:01","date_gmt":"2021-02-01T22:10:01","guid":{"rendered":"http:\/\/andreas-wolter.com\/?p=6092"},"modified":"2025-07-28T17:17:45","modified_gmt":"2025-07-28T22:17:45","slug":"202102_principle-of-least-privilege-polp","status":"publish","type":"post","link":"https:\/\/andreas-wolter.com\/en\/202102_principle-of-least-privilege-polp\/","title":{"rendered":"Principle of Least Privilege (POLP)"},"content":{"rendered":"<section  class='av_textblock_section av-q4yvfw-ce07f7a87a866c9a00e04fea99e049ac '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><h3>Principle of Least Privilege (POLP)<\/h3>\n<p><em>(part 1 of my series of articles on <a href=\"https:\/\/andreas-wolter.com\/en\/202109_introduction-into-security-principles-in-the-context-of-database-systems\/\">security principles in Microsoft SQL Servers &#038; Databases<\/a>)<\/em><\/p>\n<p>The first security principle that I am going to discuss is one that most System Administrators are familiar with: the \u201cprinciple of least privilege\u201d (short: POLP). It demands that the required permissions for a task shall <u>only grant access to the needed information or resources that a task requires<\/u>. When permissions are granted, we shall grant the least privileges possible.<\/p>\n<p>POLP is so crucial because initially it is the privileges that any attacker is targeting. When developing an application, using a <em>least-privileged user account<\/em> (LUA) is the first rule of engagement.<\/p>\n<p style=\"text-align: left; padding-left: 40px;\"><em>Note<\/em><br \/>\n<a href=\"https:\/\/docs.microsoft.com\/en-us\/windows-server\/security\/user-account-control\/how-user-account-control-works\" target=\"_blank\" rel=\"noopener\"><em>User Account Control<\/em><\/a> (UAC) in Windows is a feature that Microsoft developed to assist administrators in working with least-privileges by default and elevate to higher permission only when needed.<\/p>\n<p>You may also know that Microsoft recommends separating service accounts. This security best practice is generally referred to as <strong><em>service account isolation<\/em><\/strong> and is related to POLP: Using distinct service accounts prevents increased privileges, which happens easily when you share an account to be used for multiple purposes and as a consequence, the privileges are merged. &#8211; This would violate the principle of least privilege.<br \/>\nBoth POLP and service account isolation help reducing the attack surface (aka <strong><em>attack surface reduction<\/em><\/strong>).<\/p>\n<ul>\n<li>Read more on this topic here: <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/connect\/ado-net\/sql\/sql-server-security?view=sql-server-ver15\" target=\"_blank\" rel=\"noopener\">SQL Server security &#8211; SQL Server | Microsoft Docs<\/a><br \/>\nand here: <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/security\/surface-area-configuration?view=sql-server-ver15\" target=\"_blank\" rel=\"noopener\">Surface Area Configuration &#8211; SQL Server | Microsoft Docs<\/a><\/li>\n<\/ul>\n<p>Service account isolation also prevents <strong><em>lateral movement<\/em><\/strong> between services if an attacker gained access to one service. You see how one thing is connected to another in Security?<\/p>\n<p style=\"padding-left: 40px;\"><em>Note<\/em><br \/>\n<strong><em>Lateral movement is<\/em><\/strong> a common attack strategy to move from one target to the next: If the main target (for example the database server) cannot be breached into directly, attackers try to gain foothold in some other server in the system within the same network and then launch other attacks to try to get to the final goal, server by server or service by service.<\/p>\n<\/div><\/section>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-o572gs-48042be8b7ac533fdcce664f13e279f6\">\n.flex_column.av-o572gs-48042be8b7ac533fdcce664f13e279f6{\nborder-radius:0px 0px 0px 0px;\npadding:0px 0px 0px 0px;\n}\n<\/style>\n<div  class='flex_column av-o572gs-48042be8b7ac533fdcce664f13e279f6 av_one_full  avia-builder-el-1  el_after_av_textblock  el_before_av_one_full  first flex_column_div av-zero-column-padding  column-top-margin'     ><section  class='av_textblock_section av-m53h3w-17c66ee4e374c0cc63bf46fb226b256a '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><h4><a name=\"_Toc58433746\"><\/a>Principle of Least Privilege in the SQL realm<\/h4>\n<p>Let\u2019s look at some examples within the SQL Server engine (applying to on-prem as well as our Azure SQL-products):<\/p>\n<h5>Example 1, read-access to data<\/h5>\n<p>A typical example within SQL Server would be: To allow a User to only read data from a small set of tables, ideally defined by a schema-boundary, we have the SELECT-Permission, grantable at the schema- (or even table-) level. There is no need to grant SELECT at the whole database, or to grant anything other than SELECT.<br \/>\nIn the code-snippet below we see that there are many tables in different schemas (Application, Purchasing, Sales) within the database <em>WideWorldImporters<\/em>. Instead of granting Select in the whole database, we chose to grant the user <em>Shakti<\/em> the permission at the schema scope. As long as this schema really contains only objects that Shakti needs access to, this is a best practice as it greatly reduces the management and reporting overhead compared to granting permissions at the object-level.<\/p>\n<\/div><\/section>\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-kjh56k-09124dc10b77e605372e28e361d16f36\">\n.avia-image-container.av-kjh56k-09124dc10b77e605372e28e361d16f36 img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-kjh56k-09124dc10b77e605372e28e361d16f36 .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-kjh56k-09124dc10b77e605372e28e361d16f36 av-styling- avia-align-center  avia-builder-el-3  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-6082 avia-img-lazy-loading-not-6082 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema.png\" alt='POLP-Example' title='POLP_1_Select_on_Schema'  height=\"975\" width=\"2397\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema.png 2397w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-600x244.png 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-300x122.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-768x312.png 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-1030x419.png 1030w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-1500x610.png 1500w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-705x287.png 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_1_Select_on_Schema-450x183.png 450w\" sizes=\"(max-width: 2397px) 100vw, 2397px\" \/><\/div><\/div><\/div>\n<section  class='av_textblock_section av-ju90a4-5f9b4d229698b253b3d5dffc787a8051 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p style=\"padding-left: 30px;\"><em>Tip<\/em><\/p>\n<p style=\"padding-left: 30px;\">An alternative is to use stored procedures for all data access, which would allow even better control and completely hide the schema from Users.<\/p>\n<p>That was easy, wasn\u2019t it?<\/p>\n<\/div><\/section><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-hy037g-0affe9fb278cf542e6a444fcb1d159e9\">\n.flex_column.av-hy037g-0affe9fb278cf542e6a444fcb1d159e9{\nborder-radius:0px 0px 0px 0px;\npadding:0px 0px 0px 0px;\n}\n<\/style>\n<div  class='flex_column av-hy037g-0affe9fb278cf542e6a444fcb1d159e9 av_one_full  avia-builder-el-5  el_after_av_one_full  avia-builder-el-last  first flex_column_div av-zero-column-padding  column-top-margin'     ><section  class='av_textblock_section av-fgrfcc-47defd22b6c0395b27f18c4784d3289b '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><h5>Example 2, creating user accounts<\/h5>\n<p>Unfortunately, not everything is implemented to always ensure POLP.<\/p>\n<p>Let\u2019s take another example:<\/p>\n<p>You want to delegate the ability to create new Logins in SQL Server.<br \/>\nThe minimal permission available is ALTER ANY LOGIN. Ok, so now this person can create new Logins, and maybe also Dropping them is ok.<\/p>\n<p>But: With this permission comes the ability to change the password of any SQL Login (\u201cALTER LOGIN \u2026 WITH PASSWORD=&#8217;NewPassword&#8217;).<\/p>\n<p>This can be an unwanted scenario as this would enable this person to essentially take over other accounts.<\/p>\n<p style=\"padding-left: 40px;\"><em>Note<\/em><br \/>\nThis would not work if the Account were a Windows Domain or Azure Active Directory account. This is where a separation of the authenticating system from SQL Server has a real advantage. (This is a great example of <em>Separation of Duties<\/em> btw.)<\/p>\n<h5>Example 3, changing table structures<\/h5>\n<p>What about the following?<br \/>\nSay you want to allow a developer to add a set of new columns to the existing tables. (For example, for logging purposes, you need to include the timestamp of any new row.)<\/p>\n<p>The minimal permission to change tables\/add new columns is the ALTER-permission on each individual table (it cannot be done on schema-level).<\/p>\n<\/div><\/section>\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-eqgpjw-1d367e39e1f88c61911d3970024c6fcf\">\n.avia-image-container.av-eqgpjw-1d367e39e1f88c61911d3970024c6fcf img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-eqgpjw-1d367e39e1f88c61911d3970024c6fcf .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-eqgpjw-1d367e39e1f88c61911d3970024c6fcf av-styling- avia-align-center  avia-builder-el-7  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-6084 avia-img-lazy-loading-not-6084 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_2_Alter_on_Table-300x112.png\" alt='' title='POLP_2_Alter_on_Table'  height=\"112\" width=\"300\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_2_Alter_on_Table-300x112.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_2_Alter_on_Table-600x224.png 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_2_Alter_on_Table-450x168.png 450w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_2_Alter_on_Table.png 683w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/div><\/div><\/div>\n<section  class='av_textblock_section av-d2eprg-2e1538f26bd182ec0848f28a027e42b4 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>In my example you can see that adding new columns works fine, also dropping the table is not allowed.<\/p>\n<\/div><\/section>\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-b16m2k-1f653fc97fda388435f9b99d28f53ab7\">\n.avia-image-container.av-b16m2k-1f653fc97fda388435f9b99d28f53ab7 img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-b16m2k-1f653fc97fda388435f9b99d28f53ab7 .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-b16m2k-1f653fc97fda388435f9b99d28f53ab7 av-styling- avia-align-center  avia-builder-el-9  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-6086 avia-img-lazy-loading-not-6086 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column-300x126.png\" alt='' title='POLP_3_Alter_on_Table_Add_Column'  height=\"126\" width=\"300\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column-300x126.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column-600x252.png 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column-705x296.png 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column-450x189.png 450w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_3_Alter_on_Table_Add_Column.png 749w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/div><\/div><\/div>\n<section  class='av_textblock_section av-8njmf0-52cfe29bd38ad7bd8c73ac2829ac33d8 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>But:<\/p>\n<p>Instead of adding new columns this user could also drop existing columns. This is covered under the same least permission\/privilege:<\/p>\n<\/div><\/section>\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-7yxrzg-cb934912eb1fe5afdbb2294c32eb5001\">\n.avia-image-container.av-7yxrzg-cb934912eb1fe5afdbb2294c32eb5001 img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-7yxrzg-cb934912eb1fe5afdbb2294c32eb5001 .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-7yxrzg-cb934912eb1fe5afdbb2294c32eb5001 av-styling- avia-align-center  avia-builder-el-11  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-6088 avia-img-lazy-loading-not-6088 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_4_Alter_on_Table_Drop_Column-300x123.png\" alt='' title='POLP_4_Alter_on_Table_Drop_Column'  height=\"123\" width=\"300\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_4_Alter_on_Table_Drop_Column-300x123.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2021\/01\/POLP_4_Alter_on_Table_Drop_Column.png 418w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/div><\/div><\/div>\n<section  class='av_textblock_section av-5uwalo-9ad79f06b71df626884837cbf3c5c3fb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>Or: You want them to only create new tables but disallow to change existing tables. Since the required permissions for that are: CREATE TABLE on Database + ALTER on the schema, they could also drop tables. With permissions alone this cannot be solved. This is a common reason for the use of DDL Triggers as a preventative control. (I demonstrated an example of a DDL Trigger in this Blog-Article: <a href=\"https:\/\/andreas-wolter.com\/en\/202012-logging-schema-changes-ddl-trigger\/\">Logging Schema-changes in a Database using DDL Trigger<\/a>, which can easily be adjusted to prevent certain statements altogether by rolling them back.)<\/p>\n<\/div><\/section>\n<section  class='av_textblock_section av-4i1gp8-8c120c304d6452b90ba194249be95370 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><h4>Conclusion<\/h4>\n<p>The more you dive into this subject and real-world implementation, the more you will realize that this apparently basic security principle is much tougher than you may initially have expected.<\/p>\n<p>The permission system of SQL Server is very granular, vast, and continuously growing. (SQL Server 2019 provides 248 permissions and Azure SQL Database exposes 254 permissions as of December 2020.)<\/p>\n<p>While some of the examples above are reasonable, we need to balance every decision for every new permission and look at it from multiple angles whenever a new functionality or command is implemented. For example:<\/p>\n<ol>\n<li>Which other commands and tasks are covered under the same permission?<\/li>\n<li>How do they relate to the functionality at hand?<\/li>\n<li>Is the use of the new functionality\/command alone a common scenario?<\/li>\n<\/ol>\n<p>Having permissions on parts of Table-structures, like adding columns but not dropping them, would increase the complexity of the permission-system and hence the compromise to have just one ALTER-permission on table DDL was made.<\/p>\n<p>That said, I know there are examples where the balance is not right, and SQL Server can be improved, like TRUNCATE TABLE requiring ALTER on the table as well and others.<\/p>\n<p>Feel free to let me know where you believe that POLP is seriously unbalanced, and more granularity is required to reach compliance.<\/p>\n<p>Happy securing<\/p>\n<p>Andreas<\/p>\n<\/div><\/section>\n<section  class='av_textblock_section av-36a2jw-a51b433e6f36758d234167aa48b726cc '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><h4><a name=\"_Toc58433748\"><\/a>Resources<\/h4>\n<ul>\n<li>Wikipedia: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_privilege\" target=\"_blank\" rel=\"noopener\">https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_privilege<\/a><\/li>\n<li><a href=\"https:\/\/andreas-wolter.com\/en\/schema-design-for-sql-server-recommendations-for-schema-design-with-security-in-mind\/\">Schema-design for SQL Server: recommendations for Schema design with security in mind<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/sql-server\/install\/security-considerations-for-a-sql-server-installation?view=sql-server-ver15#isolated_services\" target=\"_blank\" rel=\"noopener\">Security Considerations &#8211; SQL Server<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/security\/fundamentals\/identity-management-best-practices#lower-exposure-of-privileged-accounts\" target=\"_blank\" rel=\"noopener\">Azure identity &#038; access security best practices<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/defender-for-identity\/use-case-lateral-movement-path\" target=\"_blank\" rel=\"noopener\">Understand and use Lateral Movement Paths with Microsoft Defender for Identity <\/a><\/li>\n<li><a href=\"https:\/\/azure.microsoft.com\/en-us\/blog\/detecting-threats-with-azure-security-center\/\" target=\"_blank\" rel=\"noopener\">Detecting threats with Azure Security Center | Azure Blog and Updates<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/connect\/ado-net\/sql\/sql-server-security?view=sql-server-ver15\" target=\"_blank\" rel=\"noopener\">SQL Server security &#8211; SQL Server | Microsoft Docs<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/security\/surface-area-configuration?view=sql-server-ver15\" target=\"_blank\" rel=\"noopener\">Surface Area Configuration &#8211; SQL Server | Microsoft Docs<\/a><\/li>\n<\/ul>\n<\/div><\/section><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":4,"featured_media":6082,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[327,57],"tags":[205,27,232],"class_list":["post-6092","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-schemas-en","category-security-en","tag-least-privilege","tag-security-en","tag-sicherheit-en"],"_links":{"self":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6092","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=6092"}],"version-history":[{"count":4,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6092\/revisions"}],"predecessor-version":[{"id":6920,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/6092\/revisions\/6920"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media\/6082"}],"wp:attachment":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media?parent=6092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/categories?post=6092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/tags?post=6092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}