Slide 1

Slide 1 text

Authorization to implement with Extensible Effect Scala Matsuri 2023 @machuz &YUFOTJCMF& ff FDUͰ࣮૷͢ΔೝՄ

Slide 2

Slide 2 text

About me > Tsubasa Matsukawa - SWE at Alp.Inc @wing_007 @machuz ࣗݾ঺հ

Slide 3

Slide 3 text

Our Products > Scalebase This is software for launch up and managing and revenue management their subscription-based services. ΞϧϓͰ͸4DBMFCBTFͱ͍͏αϒεΫϦϓγϣϯ؅ཧͱ ܦӦ෼ੳͷ4BB4ϓϩμΫτΛఏڙ͍ͯ͠·͢

Slide 4

Slide 4 text

What is Authentication and Authorization? ೝূͱೝՄͱ͸ʁ

Slide 5

Slide 5 text

AuthN ~AutheNtication~ AuthN is to verify“who”the subject is. ೝূ͸ɺର৅͕ʮ୭ʯͰ͋Δ͔Λ֬ೝ͢Δ͜ͱͰ͢

Slide 6

Slide 6 text

AuthZ ~AuthoriZation ~ AuthZ is a control that allows any subject to allow or deny action on any resource. ೝՄ͸ɺ`೚ҙͷର৅`͕b೚ҙͷϦιʔε`ʹରͯ͠ߦ͏ ΞΫγϣϯͷڐՄڋ൱Λ੍ޚ͢Δ͜ͱͰ͢ Principal Resource "DUJPO "MMPX %FOZ

Slide 7

Slide 7 text

This time, I will talk about authorization. ࠓճ͸ೝՄʹ͍͓ͭͯ࿩͠·͢

Slide 8

Slide 8 text

Some of the contents overlap with last year’s “Alp-original Eff peals”. ڈ೥ൃදͨ͠AΞϧϓͷ& ff ಠࣗ& ff FDUूAͷҰͭͱͯ͠ ঺հ͍ͯ͠ΔͷͰҰ෦ॏෳ͢Δ಺༰΋͋Γ·͢

Slide 9

Slide 9 text

Authorization is complex and coverage is wide-ranging Presenter Controller Repository(DB etc..) UseCase Domain Masking item Execute endpoint Filter resource read/write auhorization Execute UseCase Ramification domainLogic Execute domainLogic ೝՄ͸ద༻ൣғ͕޿͘ɺཁ݅࣍ୈͰ͸1SFTFOUFSd%PNBJO·Ͱ Өڹ͠͏Δɺͱͯ΋ෳࡶͳ֓೦Ͱ͢ > Because authz is abstract, it is often implemented in close coupling with concrete requirements, resulting in inflexibility.

Slide 10

Slide 10 text

this is not much of a problem while the system is small and the requirements are simple. γεςϜ͕খ͘͞ɺཁ͕݅γϯϓϧͳ͏ͪ͸ɺ ͋·Γ໰୊ʹ͸ͳΓ·ͤΜɻ

Slide 11

Slide 11 text

Simple-Case ͨͱ͑͹ɺೝূ͕௨Ε͹γεςϜ্ͷ͢΂ͯͷૢ࡞Λ ڐՄ͢Δ৔߹ͳͲ͸ೝՄΛҙࣝ͢Δඞཁ΋ͳ͍Ͱ͠ΐ͏ɻ => whatever you can do > For example, if you want to allow all operations on a system as long as AuthN is given, you do not need to be aware of the Authz.

Slide 12

Slide 12 text

> It can get very complicated if you want to delegate some of the privileges or allow/deny operations through multiple paths. ݖݶͷҰ෦Λҕৡͨ͠Γɺෳ਺ͷܦ࿏Ͱૢ࡞ΛڐՄڋ൱ͨ͠ ͍৔߹͸ɺඇৗʹෳࡶʹͳΔՄೳੑ͕͋Γ·͢ɻ => decision complicated-Case && What action? What resources are targeted? Paid for? has Manual Permission? is Developer? is BAN? etc… or user|token

Slide 13

Slide 13 text

How complicated is it? ͲͷΑ͏ʹෳࡶͳͷͰ͠ΐ͏͔ʁ

Slide 14

Slide 14 text

Case1: Multi principals > When it becomes necessary to manage the permissions of multiple principals (users, API tokens, operators, etc...), without a unified management mechanism, similar implementations will increase. Authz attribute associated with the API key Authz attribute associated with the User ෳ਺ͷϓϦϯγύϧ͕ଘࡏ͢Δࡍɺ౷Ұతʹ؅ཧ͍ͯ͠ͳ͍ͱ ࣅͨΑ͏ͳϩδοΫ͕૿͑ͯ͠·͍·͢ etc…

Slide 15

Slide 15 text

Case2: Multiple authorization paths > There are a wide variety of paths to be authorized. > If not managed in a unified manner, decisions must be made for each path, and the logic becomes huge! AuthZ attribute A - When a bill is paid successfully - When delegating to an API key - When creating a user - When manually granted ݖݶ෇༩͞ΕΔܦ࿏͸ଟذʹΘͨΓ·͢ɻ ౷Ұతʹ؅ཧ͠ͳ͍ͱɺܦ࿏ຖʹ൑ఆ͕ඞཁʹͳΓɺ ϩδοΫ͕ڊେԽ͠·͢

Slide 16

Slide 16 text

There must be many other factors that complicate the process. ͜ΕΒҎ֎ʹ΋ෳࡶʹͳΔཁҼ͸͋ΔͰ͠ΐ͏

Slide 17

Slide 17 text

How can we avoid tight coupling between AuthZ and the unique requirements and handle AuthZ well? "VUI;ͱݸผཁ݅ͷີ݁߹Λආ͚ɺ "VUI;Λ͏·͘ѻ͏ʹ͸Ͳ͏͢Ε͹͍͍ͷ͔

Slide 18

Slide 18 text

Separation of management and client of judgment. զʑ͸͜ͷෳࡶੑʹbೝՄͷ؅ཧଆ`ͱ b൑ఆΛґཔ͢Δଆ`Λ෼͚Δ͜ͱͰରԠ͢Δ͜ͱʹ͠·ͨ͠ Management ·Principal(ID&Type) ·Authority attributes ·Target resources Judgement Client The decision is made by recognizing and querying the principal's ID, required authorization attributes, and resource ID to obtain results. It should also be able to combine the results with the results of proprietary requirement-specific logic. Mapping of the following elements. State of this mapping. ·Allocation path ·Term ·enable/disable With this information, return a decision request from the client.

Slide 19

Slide 19 text

Components of Authz ೝՄͷߏ੒ཁૉ

Slide 20

Slide 20 text

Principal & Resource ೝՄ͸1SJODJQBMͱ3FTPVDF͔Βߏ੒͞Ε·͢ Principal Resource

Slide 21

Slide 21 text

Principal? Resource? 1SJODJQBMೝՄର৅ 3FTPVSDFೝՄର৅ͷૢ࡞ʹӨڹ͢Δର৅ > Principal - Authorization target ex. User, AcessToken etc… > Resource - object that affect principal operation. - What is treated as Principal may also be treated as Resource.

Slide 22

Slide 22 text

Principal & Resource has Authz attribute ͜ΕΒʹ͸ͦΕͧΕೝՄʹ࢖͏ଐੑΛ͍࣋ͨͤͯ·͢ "#"$ Principal Resource Policy Scope

Slide 23

Slide 23 text

Policy can also specify restrictions on specific resources 1PMJDZʹ͸ಛఆͷ3FTPVSDFʹର͢Δ੍ݶ΋ࢦఆՄೳͰ͢ Principal Resource Policy Scope ResourceId

Slide 24

Slide 24 text

Policy ? Scope ? 1PMJDZ͸1SJODJQBMʹ෇༩͞ΕΔೝՄଐੑ 4DPQF͸3FTPVSDFʹ෇༩͞ΕΔೝՄ৘ใ > Policy - Authorization attribute assigned to Principal. - In addition to authorization information, it has resource id and other information used for id-based filters. - Store in Database. > Scope - Authorization attribute assigned to Resource. - Describe in code.

Slide 25

Slide 25 text

Policy can also specify restrictions on specific resources ઃఆ͞Ε͍ͯΔ4DPQFΛ Ϣʔβʔ͕ଐੑͱͯ͠อ͍࣋ͯ͠Δ৔߹ʹೝՄ͕௨Γ·͢ Principal Resource Policy Scope View:SomeResource View:SomeResource DBOWJFX ○

Slide 26

Slide 26 text

Attributes of denial are given priority over those of permission ڋ൱ͷଐੑ͸ڐՄͷଐੑΑΓ༏ઌͯ͠ѻΘΕ·͢ Principal Resource Policy Scope View:SomeResource View:SomeResource Banned:All SFKFDU ✗

Slide 27

Slide 27 text

AuthZ Effect ͜ΕΒͷߏ੒ཁૉͱɺ& ff ͷࣜͱ࣮ߦΛ෼཭͢Δੑ࣭Λར༻ ͠ɺೝՄ& ff FDUΛ࣮૷͠·͢

Slide 28

Slide 28 text

·ͣ͸"VUI;Λར༻͢ΔίϚϯυΛ"%5Ͱදݱ͠·͢ Design “AuthZ” effect > Commands that use AuthZ are expressed in ADT.

Slide 29

Slide 29 text

࣍ʹίϚϯυΛΤϑΣΫτελοΫʹੵΉ ίϯετϥΫλΛ༻ҙ͠·͢ Design “AuthZ” effect > Next, we load the commands onto the effects stack constructor

Slide 30

Slide 30 text

͜ΕͰೝՄͷ؅ཧଆɺґཔଆͷࣜΛ ߏஙͰ͖ΔΑ͏ʹͳΓ·ͨ͠ Build Program > The administrative and requesting side of the authorization equation It is now possible to construct.

Slide 31

Slide 31 text

͜ͷΑ͏ʹಛఆͷϏδωεϩδοΫ΍ σʔλྔͳͲ͕བྷΉΑ͏ͳ4QFDJ fi Dͳ৚݅ͱ΋߹੒ՄೳͰ͢ Build Program > Commands that use AuthZ are expressed in ADT.

Slide 32

Slide 32 text

Interpreter ࣍ʹ*OUFSQSFUFSͷ࣮૷Λߟ͑ͯΈ·͢

Slide 33

Slide 33 text

The premise is to adopt a monolith of modules and implementation of the interpreter is a query to AuthZ-ctx. Presenter Controller Adapter UseCase Domain Lib Subscription-ctx Presenter Controller Adapter UseCase Domain Lib Authz-ctx judgement request Prerequisite લఏͱͯ͠ɺฐࣾ͸ϞδϡϥϞϊϦεΛ࠾༻͓ͯ͠Γɺ ΠϯλϓϦλͷ࣮૷͸"VUI;DUY΁ͷ໰͍߹ΘͤͰ͢ Presenter Controller Adapter UseCase Domain Lib Payment-ctx add policy request

Slide 34

Slide 34 text

In this way, the gRPC Client will query Authz-ctx via gRPC Client. Implement Interpreter ͜ͷΑ͏ʹ࣮૷͸͢΂ͯγϯϓϧʹH31$$MJFOUܦ༝Ͱ "VUI;DUYʹ໰͍߹Θ͍ͤͯ·͢

Slide 35

Slide 35 text

In this way, we try to keep the interests of authorization, which tend to combine We try to keep them sparse. ೝՄଐੑͷ؅ཧͱ4DPQFͱଐੑಥ߹൑ఆ෦෼ΛผίϯςΩετ ʹ੾Γग़͢͜ͱͰɺೝՄͷؔ৺ࣄΛૄʹอͭΑ͏ʹ͍ͯ͠·͢

Slide 36

Slide 36 text

Client-side authorization settings ࠷ޙʹɺΫϥΠΞϯτଆͰ ͲͷΑ͏ʹೝՄΛઃఆ͢Δ͔͝঺հ͠·͢

Slide 37

Slide 37 text

Setting up in a nutshell is a difficult problem! ೝՄͷઃఆ΋·ͨ೉͍͠໰୊Ͱ͢ɻ ཁ݅ͱີ݁߹͠΍͘͢ɺϩδοΫͰҙࣝͨ͋͘͠Γ·ͤΜ

Slide 38

Slide 38 text

Resource exists in various places, making it difficult to handle in a unified handling. ೝՄͷର৅Ͱ͋Δ3FTPVSDFͷ4DPQF͕͞·͟·ͳ৔ॴʹ ଘࡏ͢ΔͨΊɺ౷ҰతͳϋϯυϦϯά͕೉͍͠ੑ࣭΋͋Γ·͢

Slide 39

Slide 39 text

Solutions ͜ΕΛએݴతͳ4DPQFઃఆɺ4UBUFϞφυɺΠϯλϓϦλ࣮ߦ ࣌ʹೝՄνΣοΫΛڧ੍తʹ૊ΈࠐΉ͜ͱͰղܾͰ͖·ͨ͠ > Declarative scope setting > State monad > Enforce authorization checks at interpreter execute

Slide 40

Slide 40 text

Declarative scope setting υϝΠϯϞσϧͷ*%౳ʹείʔϓΛ෇༩͢Δ Assign scope to domain model IDs, etc…

Slide 41

Slide 41 text

State monad ಠࣗΤϑΣΫτͰɺ ઃఆͨ͠είʔϓΛ4UBUF.POBEʹQVU͠·͢ Put the scope set by the original effect to State

Slide 42

Slide 42 text

State monad είʔϓ͸ࢦఆͷܕʹแΊ͹ ࣗಈͰΤϑΣΫτελοΫʹੵ·ΕΔΑ͏ʹ͠·ͨ͠ 
 TDBMB fi YͰܕͷࢦఆ͕࿙Ε͍ͯΕ͹ίϯύΠϧΤϥʔʹ͠·͢ > By setting the return value of the interface to the specified type, the scope is automatically loaded onto the effects stack. > If the type specification is omitted, `scalafix` will generate a compile error.

Slide 43

Slide 43 text

͜ͷ࢓૊ΈʹΑͬͯɺࣜʹ͸࣮ߦʹඞཁͳೝՄείʔϓ͕಺แ ͞Ε·͢ɻ͜ΕͱϢʔβʔͷଐੑͰ൑ఆΛ͠·͢ Build Program &GG<3 "> "QJ,FZ3FBE $POUSBDU"MM #JMMJOH3FBE $POUSBDU"MM > In the assembled expression, The authorization scope necessary for execution are encapsulated. > This and the user's attributes are used to determine.

Slide 44

Slide 44 text

State monad ֤૚ʹލͬͨೝՄείʔϓ΋ͭͷ4UBUFͰ؅ཧͰ͖·͢ > This allows for the management of authorization scopes across all tiers in a single State. Presenter Controller Repository(DB etc..) UseCase Domain Set Scope A Set Scope B Set Scope C,D Set Scope E Set Scope F State[List[A,B,C,D,E,F], X]

Slide 45

Slide 45 text

By using this, the authorization for the entire process only needs to be checked once! ͜ΕΛར༻͢Δ͜ͱͰɺ ॲཧશମͷೝՄΛҰճͷνΣοΫͰࡁ·ͤΔ͜ͱ͕Ͱ͖·ͨ͠

Slide 46

Slide 46 text

Add authorization checks to the end of the expression & ff FDUΛΠϯλϓϦλʹ౉͢खલͰɺ 1SJODJQBMͷݖݶϦΫΤετΛڬΈ·͢ Before executing your own effects Interrupt the authorization request of the Principal

Slide 47

Slide 47 text

ࣜͷධՁ௚લʹೝՄνΣοΫͷࣜΛ࢓ࠐΊΔͷͰɺ ࣜશମʹؚ·ΕΔೝՄଐੑʹର͢Δ൑ఆ͕ՄೳͰ͢ Add authorization checks to the end of the expression > In the assembled expression, The authorization attributes necessary for execution are encapsulated.

Slide 48

Slide 48 text

Enforce authorization checks at interpreter execute #BUDIͳͲɺݖݶνΣοΫΛলུ͍ͨ͠έʔεͰ͸ লུͰ͖·͢ Can be omitted in cases where you want to omit permission checks, such as in batches

Slide 49

Slide 49 text

Enforce authorization flow ೝՄͷద༻ϑϩʔ &YQSFTTJPO"TTFNCMZ1IBTF %FGJOFBDPNNBOEUPTFUUIF SFRVJSFETDPQFUP4UBUFBUBOZ QPJOUJOUIFDPEFCBTF :PVXJMMIBWFBOFYQSFTTJPOXJUI UIFTDPQFZPVOFFEUPFYFDVUFJU $BMMJOUFSQSFUFS1IBTF 3VOJOUFSQSFUFS1IBTF QSPHSBNSVO authzInterpreter.run( program << requestAuthzScope(principalId) ) WBMQSPHSBN&GG<3 "> Stack State[List[ActionCompose], A] & others(DB,Task,Either, etc..) 1BTTFTBOFYQSFTTJPOXJUITDPQF UPUIFJOUFSQSFUFS *ODPSQPSBUFBVUIPSJ[BUJPOSFRVFTU DPNNBOETXIFOQBTTJOH 5IJTBMMPXTVTUPFOGPSDFUIF BVUIPSJ[BUJPOSFRVFTUXIFO PCUBJOJOHs&GG<3 ">"s 8IFOUIFrSFRVFTU"VUI[4DPQF DPNNBOEJTFWBMVBUFE BBMMPX EFOZEFDJTJPOJTNBEFCBTFEPOUIF TDPQFTFUBOEQFSNJTTJPOT BTTPDJBUFEXJUIUIFQSJODJQBM *GUIFEFDJTJPOJTEFOZ BO &JUIFSMFGUJTBEEFEUPUIFFGGFDU TUBDLBOEUIFDPNQVUBUJPOJT TUPQQFE for { state <- get[U, List[ActionComposing]] attachedPolicy <- showPolicy(principalId) attachedAction = attachedPolicy.policies.map(_.action) …

Slide 50

Slide 50 text

͜ΕΒͷϝϦοτΛڗडͰ͖ΔΑ͏ʹͳΓ·ͨ͠ Pros > Scopes set up in various places can be collected by State monad. > Can create a situation where an authorization check is mandatory to evaluate an expression. > By placing the permission check before execution, it is no longer necessary to separate implementations based on whether permission checks are required or not.

Slide 51

Slide 51 text

‘Eff’ is Good! 👍👍 & ff ͸͍͍ͧʂ

Slide 52

Slide 52 text

Thanks!