Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Designing with capabilities
(DDD Europe 2017)
@ScottWlaschin
fsharpforfunandprofit.com/cap
DDD
API
Design
Security
Design
Not about OAuth, JWT etc
DDD
API
Design
Security
Design
Topics
• What does security have to do with design?
• Introducing capabilities
• API design with capabilities
• Design con...
WHAT DOES SECURITY
HAVETO DO WITH DESIGN?
Transparent
Opaque
It’s all about
security, right?
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam,
eaque...
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam,
eaque...
David Parnas, 1971
• If you make information available:
– Programmers can’t help but make use of it
– Even if not in best ...
Can’t do
anything
Just right Unnecessary
coupling
In the large: Bounded Contexts
In the small: Interface Segregation Princ...
Can’t get your
work done
Too much information available
Just right Potential for
abuse
Principle of Least Authority (POLA)...
Ak.a. Minimize your surface area
(to reduce chance of abuse)
Good Software Design
Intention-revealing interface
Minimize c...
Good security => Good design
Good design => Good security
Security-aware design
• "Authority" = what can you do at any point?
– Be aware of authority granted
– Assume malicious use...
Stupid people Evil people
What’s the difference? 
Security-aware design
• "Authority" = what can you do at any point?
– Be aware of authority granted
– Assume malicious use...
INTRODUCING
“CAPABILITIES”
Typical API
APIcallClient
call
I'm sorry,
Dave, I'm afraid
I can't do that
Rather than telling me what I can't do,
why not tell me what I can do?
Capability-based API
Client Service
Login
Available
Capabilities
Capability-based API
Many available
actions initially
Client Service
Use a
capability
Available
Capabilities
Capability-based API
Fewer available
actions in a
given state
API DESIGN
WITH CAPABILITIES
Client
TicTacToe
Service
Request
Response
Tic-Tac-Toe as a service
Proper name is "Noughts and Crosses" btw
TIL: "Butter, ...
Tic-Tac-Toe API (obvious version)
type TicTacToeRequest = {
player: Player // X or O
row: Row
col: Column
}
Tic-Tac-Toe API (obvious version)
type TicTacToeResponse =
| KeepPlaying
| GameWon of Player
| GameTied
Demo:
ObviousTic-Tac-Toe API
What kind of errors can happen?
• A player can play an already played move
• A player can play twice in a row
• A player c...
Intention-revealing interface
"If a developer must consider the
implementation of a component in order to
use it, the valu...
“Make illegal operations
unavailable”
Don’t let me do a bad thing and
then tell me off for doing it...
Yes, you could retu...
Client
TicTacToe
Service
New Game
Available Moves
Tic-Tac-Toe service with capabilities
Nine available
moves
Client
1st move
Available Moves
Tic-Tac-Toe service with capabilities
Eight available
moves
TicTacToe
Service
Client
Available Moves
Tic-Tac-Toe service with capabilities
2nd move
Seven available
moves
TicTacToe
Service
Client
Available Moves
Tic-Tac-Toe service with capabilities
3rd move
Six available
moves, etc
TicTacToe
Service
Client
No available
Moves
Tic-Tac-Toe service with capabilities
Winning
move
TicTacToe
Service
Tic-Tac-Toe API (cap-based version)
type MoveCapability =
unit -> TicTacToeResponse
// aka Func<TicTacToeResponse>
type Ti...
Tic-Tac-Toe API (cap-based version)
type MoveCapability =
unit -> TicTacToeResponse
// aka Func<TicTacToeResponse>
type Ti...
Tic-Tac-Toe API (cap-based version)
type MoveCapability =
unit -> TicTacToeResponse
// aka Func<TicTacToeResponse>
type Ti...
Demo:
Capability-basedTic-Tac-Toe
What kind of errors can happen?
• A player can play an already played move
• A player can play twice in a row
• A player c...
HATEOAS
Hypermedia As The Engine
Of Application State
“A REST client needs no prior knowledge
about how to interact with a...
How NOT to do HATEOAS
POST /customers/
GET /customer/42
If you can guess the API
you’re doing it wrong
Security problem!
A...
How to do HATEOAS
POST /81f2300b618137d21d /
GET /da3f93e69b98
You can only know what URIs
to use by parsing the page
Each...
Tic-Tac-Toe HATEOAS
[
{ "move": "Play (Left,Top)",
"rel": "LeftTop",
"href": "/move/ec03def5-7ea8-4ac3-baf7-b290582cd3f2" ...
Demo:Tic-Tac-Toe HATEOAS
Good security => Good design
Good design => Good security
DESIGN CONSEQUENCES
OF USING CAPABILITIES
Not just for APIs -- use these design techniques
inside a bounded context too
Example:
Read a customer from a database
Controller/
API
Business
Logic
Database
Client
Could also be Onion architecture or
Ports and Adapters -- not important
Controller/
API
Business
Logic
Database
Client
Which component decides whether you
are allowed to read the customer?
But t...
Controller/
API
Business
Logic
Database
Client
But then it doesn’t have
enough context to decide 
Which component decides...
Controller/
API
Business
Logic
Database
Client
Global
Authorizer
Are you doing this already?
Which component decides wheth...
Controller/
API
Business
Logic
Database
Client
Dependency
Injection
Which component decides whether you
are allowed to rea...
public class CustomerController : ApiController
{
readonly ICustomerDb _db;
public CustomerController(ICustomerDb db)
{
_d...
public interface ICustomerDb
{
CustomerProfile GetProfile(CustomerId id);
void UpdateProfile(CustomerId id, CustomerProfil...
public interface ICustomerDb
{
CustomerProfile GetProfile(CustomerId id);
void UpdateProfile(CustomerId id, CustomerProfil...
public interface ICustomerDb
{
CustomerProfile GetProfile(CustomerId id);
}
How much authority do you really need?
Func<CustomerId,CustomerProfile>
How much authority do you really need?
public class CustomerController : ApiController
{
Func<CustomerId,CustomerProfile> _readCust;
public CustomerController(Fu...
Controller
/API
Business
Logic
Database
Use Case
Controller
/API
Business
Logic
Database
Use Case
Controller
/API
Business...
Controller
/API
Business
Logic
Database
Use Case
Controller
/API
Business
Logic
Database
Use Case
Controller
/API
Business...
But wait, there's more!
public class CustomerController : ApiController
{
[Route("customers/{customerId}")]
[HttpGet]
public IHttpActionResult Get...
TRANSFORMING CAPABILITIES
FOR BUSINESS RULES
Capability
transformer
capability
constrained
capability
Capabilities are functions... ...so can be transformed to
impleme...
With Auditingcapability
Audited
capability
Only in office
hours
capability
Time-constrained
capability
Only Oncecapability
Once-only
capability
How to revoke access in a cap-based system?
It's hard to revoke physical keys
in the real world... But this is software!
Revokablecapability
Revokable
capability
Revoker
Revokablecapability
Revokable
capability
Revoker
Revoke
automatically
after 10 mins
capability
Short-lived
capability
Demo:Transforming Capabilities
DELEGATING AUTHORITY
USING CAPABILITIES
Reasons for access control
• Prevent any access at all.
• Limit access to some things only.
• Revoke access when you are n...
Supply
Room
Alice
Bob
Secret
Files
X
Capabilities support
decentralized delegation
Delegation of authority
example
Controller
/API
Business
Logic
Database
Use Case
Inject authority
to read just
one customer
Global
Authorizer
Services
(e....
Controller
/API
Business
Logic
Database
Use Case
Services
(e.g. Read customer and
send them email)
Inject authority
to rea...
Delegation of capabilities
Full authority
(at start up)
Parent
Component
Some capabilities
Child
Component
transformer e.g...
CONCLUSION
Common questions
• Is this overkill? Is it worth it?
– It depends....
– Useful as a thought experiment
• How does this rel...
Common questions
• Are you saying that all external IO should be
passed around as capabilities?
– Yes!You should never acc...
Common questions
• Won’t there be too many parameters?
– Less than you think!
– Counter force to growth of interfaces
– En...
Summary
• Good security  good design
– Bonus: get a modular architecture!
• Use POLA as a design principle
– Don’t trust ...
Thanks!
@ScottWlaschin
fsharpforfunandprofit.com/cap
Contact me
Slides and video here
F# consulting
Designing with capabilities (DDD-EU 2017)
Upcoming SlideShare
Loading in …5
×

Designing with capabilities (DDD-EU 2017)

3,285 views

Published on

(Video and code available at http://fsharpforfunandprofit.com/cap)

In this talk I'll look at a unusual approach to designing internal interfaces and external APIs -- a "capability-based" approach that takes the Principle Of Least Authority and applies it to software design.

When this approach is used, it produces a robust and modular design which captures the domain constraints, resulting in an API which is self-documenting and hard to misuse.

I'll demonstrate how to design and implement a capability based approach, how capabilities can be quickly combined and restricted easily, and how capabilities are a natural fit with a REST API that uses HATEOAS.

Published in: Software

Designing with capabilities (DDD-EU 2017)

  1. 1. Designing with capabilities (DDD Europe 2017) @ScottWlaschin fsharpforfunandprofit.com/cap
  2. 2. DDD API Design Security Design Not about OAuth, JWT etc
  3. 3. DDD API Design Security Design
  4. 4. Topics • What does security have to do with design? • Introducing capabilities • API design with capabilities • Design consequences of using capabilities • Transforming capabilities for business rules • Delegating authority using capabilities
  5. 5. WHAT DOES SECURITY HAVETO DO WITH DESIGN?
  6. 6. Transparent Opaque It’s all about security, right?
  7. 7. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, Temporibus autem quibus Dacei Megasystems Tech Inc necessitatibust aut officiis debitis auteo 2799 E Dragam Suite 7 quisquam saepe Itaque enieti Los Angeles CA 90002 ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Please deliver this letter A counterexample
  8. 8. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, Temporibus autem quibus Dacei Megasystems Tech Inc necessitatibust aut officiis debitis auteo 2799 E Dragam Suite 7 quisquam saepe Itaque enieti Los Angeles CA 90002 ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Please deliver this letter It’s not just about security... ...hiding irrelevant information is good design!
  9. 9. David Parnas, 1971 • If you make information available: – Programmers can’t help but make use of it – Even if not in best interests of the design • Solution: – Don’t make information available!
  10. 10. Can’t do anything Just right Unnecessary coupling In the large: Bounded Contexts In the small: Interface Segregation Principle Software Design Spectrum Too much information availableToo little information available
  11. 11. Can’t get your work done Too much information available Just right Potential for abuse Principle of Least Authority (POLA) Too little information available Security spectrum
  12. 12. Ak.a. Minimize your surface area (to reduce chance of abuse) Good Software Design Intention-revealing interface Minimize coupling Make dependencies explicit Good Security Principle of Least Authority (POLA) Ak.a. Minimize your surface area (expose only desired behavior)
  13. 13. Good security => Good design Good design => Good security
  14. 14. Security-aware design • "Authority" = what can you do at any point? – Be aware of authority granted – Assume malicious users as a design aid!
  15. 15. Stupid people Evil people What’s the difference? 
  16. 16. Security-aware design • "Authority" = what can you do at any point? – Be aware of authority granted – Assume malicious users as a design aid! • Use POLA as a software design guideline – Forces intention-revealing interface – Minimizes surface area & reduces coupling
  17. 17. INTRODUCING “CAPABILITIES”
  18. 18. Typical API APIcallClient call I'm sorry, Dave, I'm afraid I can't do that
  19. 19. Rather than telling me what I can't do, why not tell me what I can do?
  20. 20. Capability-based API
  21. 21. Client Service Login Available Capabilities Capability-based API Many available actions initially
  22. 22. Client Service Use a capability Available Capabilities Capability-based API Fewer available actions in a given state
  23. 23. API DESIGN WITH CAPABILITIES
  24. 24. Client TicTacToe Service Request Response Tic-Tac-Toe as a service Proper name is "Noughts and Crosses" btw TIL: "Butter, cheese and eggs" in Dutch
  25. 25. Tic-Tac-Toe API (obvious version) type TicTacToeRequest = { player: Player // X or O row: Row col: Column }
  26. 26. Tic-Tac-Toe API (obvious version) type TicTacToeResponse = | KeepPlaying | GameWon of Player | GameTied
  27. 27. Demo: ObviousTic-Tac-Toe API
  28. 28. What kind of errors can happen? • A player can play an already played move • A player can play twice in a row • A player can forget to check the response and keep playing
  29. 29. Intention-revealing interface "If a developer must consider the implementation of a component in order to use it, the value of encapsulation is lost." -- Eric Evans, DDD book
  30. 30. “Make illegal operations unavailable” Don’t let me do a bad thing and then tell me off for doing it... Yes, you could return errors, but...
  31. 31. Client TicTacToe Service New Game Available Moves Tic-Tac-Toe service with capabilities Nine available moves
  32. 32. Client 1st move Available Moves Tic-Tac-Toe service with capabilities Eight available moves TicTacToe Service
  33. 33. Client Available Moves Tic-Tac-Toe service with capabilities 2nd move Seven available moves TicTacToe Service
  34. 34. Client Available Moves Tic-Tac-Toe service with capabilities 3rd move Six available moves, etc TicTacToe Service
  35. 35. Client No available Moves Tic-Tac-Toe service with capabilities Winning move TicTacToe Service
  36. 36. Tic-Tac-Toe API (cap-based version) type MoveCapability = unit -> TicTacToeResponse // aka Func<TicTacToeResponse> type TicTacToeResponse = | KeepPlaying of MoveCapability list | GameWon of Player | GameTied
  37. 37. Tic-Tac-Toe API (cap-based version) type MoveCapability = unit -> TicTacToeResponse // aka Func<TicTacToeResponse> type TicTacToeResponse = | KeepPlaying of MoveCapability list | GameWon of Player | GameTied
  38. 38. Tic-Tac-Toe API (cap-based version) type MoveCapability = unit -> TicTacToeResponse // aka Func<TicTacToeResponse> type TicTacToeResponse = | KeepPlaying of MoveCapability list | GameWon of Player | GameTied type InitialMoves = MoveCapability list Where did the "request" type go? Where's the authorization?
  39. 39. Demo: Capability-basedTic-Tac-Toe
  40. 40. What kind of errors can happen? • A player can play an already played move • A player can play twice in a row • A player can forget to check the response and keep playing Is this good security or good design? All fixed now! 
  41. 41. HATEOAS Hypermedia As The Engine Of Application State “A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia.” RESTful done right
  42. 42. How NOT to do HATEOAS POST /customers/ GET /customer/42 If you can guess the API you’re doing it wrong Security problem! Also, a design problem – too much coupling.
  43. 43. How to do HATEOAS POST /81f2300b618137d21d / GET /da3f93e69b98 You can only know what URIs to use by parsing the page Each of these URIs is a capability
  44. 44. Tic-Tac-Toe HATEOAS [ { "move": "Play (Left,Top)", "rel": "LeftTop", "href": "/move/ec03def5-7ea8-4ac3-baf7-b290582cd3f2" }, { "move": "Play (Left, Middle)", "rel": "Left Middle", "href": "/move/d4532ca0-4e61-4fae-bbb1-fc11d4e173df" }, { "move": "Play (Left, Bottom)", "rel": "Left Bottom", "href": "/move/fe1bfa98-e77b-4331-b99b-22850d35d39e" } ... ]
  45. 45. Demo:Tic-Tac-Toe HATEOAS
  46. 46. Good security => Good design Good design => Good security
  47. 47. DESIGN CONSEQUENCES OF USING CAPABILITIES Not just for APIs -- use these design techniques inside a bounded context too
  48. 48. Example: Read a customer from a database
  49. 49. Controller/ API Business Logic Database Client Could also be Onion architecture or Ports and Adapters -- not important
  50. 50. Controller/ API Business Logic Database Client Which component decides whether you are allowed to read the customer? But then any other path has complete access to the database 
  51. 51. Controller/ API Business Logic Database Client But then it doesn’t have enough context to decide  Which component decides whether you are allowed to read the customer?
  52. 52. Controller/ API Business Logic Database Client Global Authorizer Are you doing this already? Which component decides whether you are allowed to read the customer?
  53. 53. Controller/ API Business Logic Database Client Dependency Injection Which component decides whether you are allowed to read the customer?
  54. 54. public class CustomerController : ApiController { readonly ICustomerDb _db; public CustomerController(ICustomerDb db) { _db = db; } [Route("customers/{customerId}")] [HttpGet] public IHttpActionResult Get(int customerId) { var custId = new CustomerId(customerId); var cust = _db.GetProfile(custId); var dto = DtoConverter.CustomerToDto(cust); return Ok(dto); }
  55. 55. public interface ICustomerDb { CustomerProfile GetProfile(CustomerId id); void UpdateProfile(CustomerId id, CustomerProfile cust); void CreateAccount(CustomerId id, CustomerProfile cust); void DeleteAccount(CustomerId id); void UpdateLoginEmail(CustomerId id, string email); void UpdatePassword(CustomerId id, string password); } How much authority do you really need?
  56. 56. public interface ICustomerDb { CustomerProfile GetProfile(CustomerId id); void UpdateProfile(CustomerId id, CustomerProfile cust); void CreateAccount(CustomerId id, CustomerProfile cust); void DeleteAccount(CustomerId id); void UpdateLoginEmail(CustomerId id, string email); void UpdatePassword(CustomerId id, string password); } How much authority do you really need?
  57. 57. public interface ICustomerDb { CustomerProfile GetProfile(CustomerId id); } How much authority do you really need?
  58. 58. Func<CustomerId,CustomerProfile> How much authority do you really need?
  59. 59. public class CustomerController : ApiController { Func<CustomerId,CustomerProfile> _readCust; public CustomerController(Func<..> readCust) { _readCust = readCust; } [Route("customers/{customerId}")] [HttpGet] public IHttpActionResult Get(int customerId) { var custId = new CustomerId(customerId); var cust = _readCust(custId); var dto = DtoConverter.CustomerToDto(cust); return Ok(dto); }
  60. 60. Controller /API Business Logic Database Use Case Controller /API Business Logic Database Use Case Controller /API Business Logic Database Use Case Global Authorizer Every controller is injected with minimal capabilities it needs (aka functions)
  61. 61. Controller /API Business Logic Database Use Case Controller /API Business Logic Database Use Case Controller /API Business Logic Database Use Case Global Authorizer Vertical slices Don't mention microservices
  62. 62. But wait, there's more!
  63. 63. public class CustomerController : ApiController { [Route("customers/{customerId}")] [HttpGet] public IHttpActionResult Get(int customerId) { var custId = new CustomerId(customerId); var readCust = authorizer.GetReadCustCap(custId); if (readCust != null) { var cust = readCust(); var dto = DtoConverter.CustomerToDto(cust); return Ok(dto); } else // return error }
  64. 64. TRANSFORMING CAPABILITIES FOR BUSINESS RULES
  65. 65. Capability transformer capability constrained capability Capabilities are functions... ...so can be transformed to implement business rules
  66. 66. With Auditingcapability Audited capability
  67. 67. Only in office hours capability Time-constrained capability
  68. 68. Only Oncecapability Once-only capability
  69. 69. How to revoke access in a cap-based system? It's hard to revoke physical keys in the real world... But this is software!
  70. 70. Revokablecapability Revokable capability Revoker
  71. 71. Revokablecapability Revokable capability Revoker
  72. 72. Revoke automatically after 10 mins capability Short-lived capability
  73. 73. Demo:Transforming Capabilities
  74. 74. DELEGATING AUTHORITY USING CAPABILITIES
  75. 75. Reasons for access control • Prevent any access at all. • Limit access to some things only. • Revoke access when you are no longer allowed. • Grant and delegate access to some subset of things. It’s not always about saying no!
  76. 76. Supply Room Alice Bob Secret Files X Capabilities support decentralized delegation
  77. 77. Delegation of authority example
  78. 78. Controller /API Business Logic Database Use Case Inject authority to read just one customer Global Authorizer Services (e.g. Read customer and send them email) Security risk & implicit dependency
  79. 79. Controller /API Business Logic Database Use Case Services (e.g. Read customer and send them email) Inject authority to read just one customer Global Authorizer
  80. 80. Delegation of capabilities Full authority (at start up) Parent Component Some capabilities Child Component transformer e.g. Only once Child Component Only during office hourstransformer Delegate capabilities Delegate capabilities
  81. 81. CONCLUSION
  82. 82. Common questions • Is this overkill? Is it worth it? – It depends.... – Useful as a thought experiment • How does this relate to DDD? – Intention-revealing interfaces – Map commands from event storming to capabilities
  83. 83. Common questions • Are you saying that all external IO should be passed around as capabilities? – Yes!You should never access any ambient authority. – You should be doing this anyway for mocking. • How do you pass these capabilities around? – Dependency injection or equivalent
  84. 84. Common questions • Won’t there be too many parameters? – Less than you think! – Counter force to growth of interfaces – Encourages vertical slices (per use-case) • Can’t this be bypassed by reflection or other backdoors? – Yes. This is really all about design not about total security.
  85. 85. Summary • Good security  good design – Bonus: get a modular architecture! • Use POLA as a design principle – Don’t trust other people to do the right thing – Don’t force other people to read the documentation! • Intention revealing interfaces – Don't force the client to know the business rules – Make interfaces more dynamic – Change the available capabilities when context changes
  86. 86. Thanks! @ScottWlaschin fsharpforfunandprofit.com/cap Contact me Slides and video here F# consulting

×