{
    "componentChunkName": "component---src-templates-article-page-template-js",
    "path": "/concepts/privileged-transitions/",
    "result": {"data":{"markdownRemark":{"frontmatter":{"title":"Privileged transitions","slug":"privileged-transitions","updated":"2020-06-25T00:00:00.000Z","category":"concepts-transaction-process","ingress":"This article introduces you to the concept of privileged transitions and how Flex uses them to invoke actions from a trusted context.","skills":null},"htmlAst":{"type":"root","children":[{"type":"element","tagName":"h2","properties":{"id":"what-are-privileged-transitions","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#what-are-privileged-transitions","ariaLabel":"what are privileged transitions permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"What are privileged transitions?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In Flex, a process transition is an edge between two states in the\ntransaction process graph. Invoking transitions is guarded in the\nprocess definition by tying them to a specific state when they can be\ntransitioned and by defining who can perform the transition. This way\ntransition requests have built-in validation of who can invoke them and\nin what state of the transaction flow."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"However, there are moments when more control is required on who can\ninitiate a transition and especially with what kind of parameters. Take\ndiscounts on pricing by leveraging discount coupons managed by a 3rd\nparty service for example. A coupon code can be validated in the client\nside by invoking the coupon service but this will not limit who will be\ntechnically able to invoke a pricing related transition with discounted\nprice parameters."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This is where privileged transitions come into play. They are\ntransaction process transitions that can be invoked only from a trusted\ncontext. In other words, this means that you can build your own server\nside validation that sits between your marketplace UI and the Flex\nMarketplace API. In the discount coupon example, this means that the\ndiscount coupon that a user has can be passed as a parameter in the\ntransition request. Server side transition request validation can invoke\na 3rd party service to verify a discount code, update pricing parameters\naccordingly, and pass those to the transition that has pricing actions\ntied to it."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"how-do-privileged-transitions-work","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#how-do-privileged-transitions-work","ariaLabel":"how do privileged transitions work permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"How do privileged transitions work?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Standard authenticated Marketplace API requests require a valid access\ntoken obtained from the Authentication API. Privileged transitions\ndiffer here by requiring a special kind of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trusted"}]},{"type":"text","value":" token to\nauthenticate properly. A trusted token can be obtained by exchanging a\nvalid access token to a trusted one in the Authentication API by\nproviding a client secret. The client secret is not to be exposed\npublicly, securing that privileged transitions can only be invoked by a\ntrusted source, i.e. your own backend implementation."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 635px; "},"children":[{"type":"text","value":"\n      "},{"type":"element","tagName":"a","properties":{"className":["gatsby-resp-image-link"],"href":"/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/a7690/auth-flow.png","style":"display: block","target":"_blank","rel":["noopener"]},"children":[{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 67.9245283018868%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoElEQVQ4y41T266bMBDk/3+sT305OtW55AokQLDBNsaGpJXmaAdISVW1eVjZzHqHnR070dZDYp+XOF8a7tsuMD72GXZZgdZH2H6A8ZH52nRczYxr26NuJyxJiws+DznedynXt22KUhk0rsfr5x5v2yOU8XeyzfGEzSHH4VQRc/2ArKj5c8ESF0Z08Yrh9oskhbIotUFeaVwag0obHpTvc92i1BZhvLFm6Vo4httPYokAIqkLI+rWoVCGRVJc1A1OlUJWKlTaEr80Dj6OJDKrUSxYsgZ8vDL6uQPBujCwqB8mzAXZXx/IpvzU8QOhMh22aYFteqZJMjM5KCOQb+lUzArPEhofOOCpuObABUuLGt++v+B9n9HNpeu17L8SdnHkgP1wndY48mDVWLorHQr+tGQxZvlrO2Mim0YpMakl+dqUJf5JuMYcL66nu3ILBI/jjZ1Kzs4RnieM0K6/vx4xrrEdO+Xe9cwvc/0v4V2ytiQ5nit87FL82ByQV4qdS8768BzhMhtKnGWK5AcsjHw9D4RyYd3KtT+xdazN+41Nkr8ACuQrdEKqxNoAAAAASUVORK5CYII='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n  "},{"type":"element","tagName":"picture","properties":{},"children":[{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/82e29/auth-flow.webp 159w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/ef33f/auth-flow.webp 318w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/f1837/auth-flow.webp 635w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/29549/auth-flow.webp 953w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/c5420/auth-flow.webp 1270w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/9b921/auth-flow.webp 2115w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/webp"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/8b9b5/auth-flow.png 159w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/fa108/auth-flow.png 318w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/53fb6/auth-flow.png 635w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/5a426/auth-flow.png 953w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/91155/auth-flow.png 1270w","/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/a7690/auth-flow.png 2115w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/png"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"src":"/docs/legacy/static/2e3c9a018a02c351be13e971e3ddfbe8/53fb6/auth-flow.png","alt":"Authentication flow with a trusted access token","title":"Authentication flow with a trusted access token","loading":"lazy","decoding":"async","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"},"children":[]},{"type":"text","value":"\n        "}]},{"type":"text","value":"\n  "}]},{"type":"text","value":"\n    "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The client secret is tied to a Marketplace API\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/concepts/applications/"},"children":[{"type":"text","value":"application"}]},{"type":"text","value":". When exchanging an access token\nto a trusted one, the client secret needs to be from the same\napplication as the client ID that was used to obtain the access token."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Remember to never expose the client secret publicly. This enables full\ncontrol over requests that invoke privileged transitions."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"how-to-use-a-privileged-transition","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#how-to-use-a-privileged-transition","ariaLabel":"how to use a privileged transition permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"How to use a privileged transition"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A privileged transition is defined by setting a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"privileged?"}]},{"type":"text","value":" attribute\nto "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"true"}]},{"type":"text","value":" for the given transition in a transaction process as follows:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"{:name :transition/request-payment\n :actor :actor.role/customer\n :actions [{:name :action/create-pending-booking}\n           {:name :action/privileged-set-line-items}\n           {:name :action/stripe-create-payment-intent}]\n :to :state/pending-payment\n :privileged? true}"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Privileged transitions are configured just like a normal transitions.\nHowever, what's special about privileged transitions is that, unlike\nnormal transitions, they can contain "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"privileged actions"}]},{"type":"text","value":". Privileged\nactions validate that they are always used in a "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trusted context"}]},{"type":"text","value":" and\nusually handle sensitive information. An example of such action is\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/references/transaction-process-actions/#actionprivileged-set-line-items"},"children":[{"type":"text","value":"privileged-set-line-items"}]},{"type":"text","value":"\nwhich allows full control over the price of a transaction, including the\ncommission."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"operator-transitions-in-the-integration-api","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#operator-transitions-in-the-integration-api","ariaLabel":"operator transitions in the integration api permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Operator transitions in the Integration API"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The Integration API\n"},{"type":"element","tagName":"a","properties":{"href":"https://www.sharetribe.com/api-reference/integration.html#transition-transaction","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"makes it possible to invoke transitions"}]},{"type":"text","value":"\nfor which the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":":actor"}]},{"type":"text","value":" is set to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":":actor.role/operator"}]},{"type":"text","value":". As the\nIntegration API authentication requires knowledge of the integration\napplication's client secret and is meant to be used only from your own\nbackend implementation, it is considered a trusted source for invoking\ntransitions. As a consequence, the operator transitions can utilize any\nprivileged actions. For instance,\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/references/transaction-process-actions/#actionprivileged-update-metadata"},"children":[{"type":"text","value":"privileged-update-metadata"}]},{"type":"text","value":"\naction can be used to update the transaction's metadata."}]}],"data":{"quirksMode":false}},"headings":[{"value":"What are privileged transitions?","depth":2},{"value":"How do privileged transitions work?","depth":2},{"value":"How to use a privileged transition","depth":2},{"value":"Operator transitions in the Integration API","depth":2}]}},"pageContext":{"slug":"privileged-transitions","category":"concepts-transaction-process"}},
    "staticQueryHashes": ["3794076007","439097193","717698143"]}