{"action":"created","comment":{"url":"https://api.github.com/repos/auth0/blog/pulls/comments/155085984","pull_request_review_id":81347387,"id":155085984,"diff_hunk":"@@ -0,0 +1,220 @@\n+---\n+layout: post_extend\n+title: \"Why Auth0 chose Serverless Extensibility\"\n+description: \"\"\n+date: 2017-12-04 10:19\n+category: Extend, Business\n+author:\n+  name: \"Bobby Johnson\"\n+  url: \"https://twitter.com/NotMyself\"\n+  mail: \"bobby.johnson@auth0.com\"\n+  avatar: \"https://cdn.auth0.com/website/blog/profiles/bobbyjohnson.png\"\n+design:\n+  bg_color: \"#3445DC\"\n+  image: https://cdn.auth0.com/website/blog/extend/why-auth0-chose-serverless-extensibility/logo.png\n+tags:\n+  - extend\n+  - serverless\n+  - webhooks\n+  - extensibility\n+related:\n+  - 2017-05-16-introducing-auth0-extend-the-new-way-to-extend-your-saas\n+  - 2017-05-19-serverless-webhooks-with-auth0-extend\n+  - 2017-08-22-for-the-best-security-think-beyond-webhooks\n+---\n+Previously, we wrote about the emerging pattern of [Serverless Extensibility](https://auth0.com/blog/why-is-serverless-extensibility-better-than-webhooks/). Examples of the concept are popping up in many of the services you use daily like [Twilio](https://www.twilio.com/functions), [Stamplay](https://stamplay.com/) and here at [Auth0](https://auth0.com/).\n+\n+How did Auth0 get to the point of offering extensibility through a serverless platform? It has been a four-year journey that predates both [Amazon Lambda](https://aws.amazon.com/lambda/) and the term Serverless. Like all innovation, it starts with resource constraints, the need to give customers the features they wanted and making sales.\n+\n+## The problem we were trying to solve\n+\n+![NASA Engineers working on MAVEN](https://cdn.auth0.com/website/blog/extend/why-auth0-chose-serverless-extensibility/engineers_working_on_the_high-gain_antenna_of_the_MAVEN_spacecraft.jpg)\n+\n+*Placed into the public domain by [NASA](http://mars.jpl.nasa.gov/multimedia/images/?s=1) using [Creative Commons](https://creativecommons.org/publicdomain/zero/1.0/)*\n+\n+In the early days at Auth0, there were two groups: Core and Field Engineering. Core focused on the core functionality of the authentication product, and the field engineers helped customers use the product in their applications. The company was discovering what customers needed in the product.\n+\n+Our customer's focus was on the authentication transaction. A lot of interesting features can attach to the process of someone trying to login:\n+\n+- Profile Enrichment\n+- Progressive Profiling\n+- Authorization\n+- Claims Transformation\n+\n+The possibilities are endless. We could not possibly build every feature at once.\n+\n+Moreover, sometimes building features into the core product for customers is not the right idea. We needed a way to try ideas out. An idea may sound great, but in practice be problematic. Investing core engineering resources to these ideas is very expensive.\n+\n+> **\"The primary use case for extensibility at Auth0 was to empower field engineers to work on the last mile solutions for the customer without involving core engineering.\"**<br />\n+> Eugenio Pace - Co-Founder, VP Customer Success\n+\n+If every interaction with a customer involved identifying an idea, putting it in the backlog and coming back to them at a later date, it would add friction to the process and turn customers away.\n+\n+## Custom code extensibility\n+\n+![NASA's \"Webb-cam\" Captures Engineers at Work on Webb at Johnson Space Center](https://cdn.auth0.com/website/blog/extend/why-auth0-chose-serverless-extensibility/34827899312_571fa2a976_k.jpg)\n+\n+*[NASA](https://www.flickr.com/photos/gsfc/34827899312) licensed under [Creative Commons 2.0](https://creativecommons.org/licenses/by/2.0/)*\n+\n+The inspiration for custom code extensibility as a solution came from spreadsheets. Excel has significant functionality out of the box, but there is always a function, macro or calculation that is not available. However, you can write them yourself directly in Excel removing the dependency on Microsoft engineers.\n+\n+> **\"We wanted a similar experience for our users. A user should be able to log in to the dashboard, write a small amount of node.js code that executes later during authorization transactions.\"**<br />\n+> Eugenio Pace - Co-Founder, VP Customer Success\n+\n+Like Excel, we wanted to offer users a really simple experience for customizing our product through code. We believed a user should be able to write their logic in an editor, debug it in place and make it live in production, all without having to stand up a service. This differed from the prevalent approach at the time for dealing with customization through Webhooks, which were hosted by the user.\n+\n+We decided to go and implement an MVP of the concept using [node sandbox](https://www.npmjs.com/package/node-sandbox\n+). It was very similar to a CGI model; spinning up a separate node process, send the rule code to execute in it and collecting the result. Execution all happened one process per authorization transaction.","path":"_posts/2017-12-04-why-auth0-chose-serverless-extensibility.markdown","position":67,"original_position":67,"commit_id":"d4f38ea5a0d9b18dbca308ece4c740c4580a1e22","original_commit_id":"d4f38ea5a0d9b18dbca308ece4c740c4580a1e22","user":{"login":"tjanczuk","id":822369,"avatar_url":"https://avatars1.githubusercontent.com/u/822369?v=4","gravatar_id":"","url":"https://api.github.com/users/tjanczuk","html_url":"https://github.com/tjanczuk","followers_url":"https://api.github.com/users/tjanczuk/followers","following_url":"https://api.github.com/users/tjanczuk/following{/other_user}","gists_url":"https://api.github.com/users/tjanczuk/gists{/gist_id}","starred_url":"https://api.github.com/users/tjanczuk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tjanczuk/subscriptions","organizations_url":"https://api.github.com/users/tjanczuk/orgs","repos_url":"https://api.github.com/users/tjanczuk/repos","events_url":"https://api.github.com/users/tjanczuk/events{/privacy}","received_events_url":"https://api.github.com/users/tjanczuk/received_events","type":"User","site_admin":false},"body":"spinning ... send ... collecting -> spinning ... sending ... collecting\r\n\r\n`Execution all happened one process per authorization transaction.` -> `Every rule execution was using a dedicated system process, which was resource intensive.`?","created_at":"2017-12-05T21:48:20Z","updated_at":"2017-12-05T21:48:20Z","html_url":"https://github.com/auth0/blog/pull/1203#discussion_r155085984","pull_request_url":"https://api.github.com/repos/auth0/blog/pulls/1203","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/auth0/blog/pulls/comments/155085984"},"html":{"href":"https://github.com/auth0/blog/pull/1203#discussion_r155085984"},"pull_request":{"href":"https://api.github.com/repos/auth0/blog/pulls/1203"}}},"pull_request":{"url":"https://api.github.com/repos/auth0/blog/pulls/1203","id":155500257,"html_url":"https://github.com/auth0/blog/pull/1203","diff_url":"https://github.com/auth0/blog/pull/1203.diff","patch_url":"https://github.com/auth0/blog/pull/1203.patch","issue_url":"https://api.github.com/repos/auth0/blog/issues/1203","number":1203,"state":"open","locked":false,"title":"Auth0 Extend Blog: Why Auth0 chose Serverless Extensibility","user":{"login":"NotMyself","id":73120,"avatar_url":"https://avatars3.githubusercontent.com/u/73120?v=4","gravatar_id":"","url":"https://api.github.com/users/NotMyself","html_url":"https://github.com/NotMyself","followers_url":"https://api.github.com/users/NotMyself/followers","following_url":"https://api.github.com/users/NotMyself/following{/other_user}","gists_url":"https://api.github.com/users/NotMyself/gists{/gist_id}","starred_url":"https://api.github.com/users/NotMyself/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NotMyself/subscriptions","organizations_url":"https://api.github.com/users/NotMyself/orgs","repos_url":"https://api.github.com/users/NotMyself/repos","events_url":"https://api.github.com/users/NotMyself/events{/privacy}","received_events_url":"https://api.github.com/users/NotMyself/received_events","type":"User","site_admin":false},"body":"![screencapture-localhost-4000-blog-why-auth0-chose-serverless-extensibility-1512506680366](https://user-images.githubusercontent.com/73120/33629775-21dac71e-d9ba-11e7-84a2-8b723d10811e.png)\r\n\r\n\r\n\r\n\r\n","created_at":"2017-11-30T01:57:49Z","updated_at":"2017-12-05T21:48:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"506a9c7e2fb411dafedd83a11f224a32c49d8281","assignee":null,"assignees":[],"requested_reviewers":[{"login":"sandrinodimattia","id":655409,"avatar_url":"https://avatars1.githubusercontent.com/u/655409?v=4","gravatar_id":"","url":"https://api.github.com/users/sandrinodimattia","html_url":"https://github.com/sandrinodimattia","followers_url":"https://api.github.com/users/sandrinodimattia/followers","following_url":"https://api.github.com/users/sandrinodimattia/following{/other_user}","gists_url":"https://api.github.com/users/sandrinodimattia/gists{/gist_id}","starred_url":"https://api.github.com/users/sandrinodimattia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sandrinodimattia/subscriptions","organizations_url":"https://api.github.com/users/sandrinodimattia/orgs","repos_url":"https://api.github.com/users/sandrinodimattia/repos","events_url":"https://api.github.com/users/sandrinodimattia/events{/privacy}","received_events_url":"https://api.github.com/users/sandrinodimattia/received_events","type":"User","site_admin":false},{"login":"eugeniop","id":737076,"avatar_url":"https://avatars2.githubusercontent.com/u/737076?v=4","gravatar_id":"","url":"https://api.github.com/users/eugeniop","html_url":"https://github.com/eugeniop","followers_url":"https://api.github.com/users/eugeniop/followers","following_url":"https://api.github.com/users/eugeniop/following{/other_user}","gists_url":"https://api.github.com/users/eugeniop/gists{/gist_id}","starred_url":"https://api.github.com/users/eugeniop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eugeniop/subscriptions","organizations_url":"https://api.github.com/users/eugeniop/orgs","repos_url":"https://api.github.com/users/eugeniop/repos","events_url":"https://api.github.com/users/eugeniop/events{/privacy}","received_events_url":"https://api.github.com/users/eugeniop/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/auth0/blog/pulls/1203/commits","review_comments_url":"https://api.github.com/repos/auth0/blog/pulls/1203/comments","review_comment_url":"https://api.github.com/repos/auth0/blog/pulls/comments{/number}","comments_url":"https://api.github.com/repos/auth0/blog/issues/1203/comments","statuses_url":"https://api.github.com/repos/auth0/blog/statuses/d4f38ea5a0d9b18dbca308ece4c740c4580a1e22","head":{"label":"auth0:serverless_at_auth0","ref":"serverless_at_auth0","sha":"d4f38ea5a0d9b18dbca308ece4c740c4580a1e22","user":{"login":"auth0","id":2824157,"avatar_url":"https://avatars1.githubusercontent.com/u/2824157?v=4","gravatar_id":"","url":"https://api.github.com/users/auth0","html_url":"https://github.com/auth0","followers_url":"https://api.github.com/users/auth0/followers","following_url":"https://api.github.com/users/auth0/following{/other_user}","gists_url":"https://api.github.com/users/auth0/gists{/gist_id}","starred_url":"https://api.github.com/users/auth0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auth0/subscriptions","organizations_url":"https://api.github.com/users/auth0/orgs","repos_url":"https://api.github.com/users/auth0/repos","events_url":"https://api.github.com/users/auth0/events{/privacy}","received_events_url":"https://api.github.com/users/auth0/received_events","type":"Organization","site_admin":false},"repo":{"id":7830124,"name":"blog","full_name":"auth0/blog","owner":{"login":"auth0","id":2824157,"avatar_url":"https://avatars1.githubusercontent.com/u/2824157?v=4","gravatar_id":"","url":"https://api.github.com/users/auth0","html_url":"https://github.com/auth0","followers_url":"https://api.github.com/users/auth0/followers","following_url":"https://api.github.com/users/auth0/following{/other_user}","gists_url":"https://api.github.com/users/auth0/gists{/gist_id}","starred_url":"https://api.github.com/users/auth0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auth0/subscriptions","organizations_url":"https://api.github.com/users/auth0/orgs","repos_url":"https://api.github.com/users/auth0/repos","events_url":"https://api.github.com/users/auth0/events{/privacy}","received_events_url":"https://api.github.com/users/auth0/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/auth0/blog","description":"auth0 blog","fork":false,"url":"https://api.github.com/repos/auth0/blog","forks_url":"https://api.github.com/repos/auth0/blog/forks","keys_url":"https://api.github.com/repos/auth0/blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/auth0/blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/auth0/blog/teams","hooks_url":"https://api.github.com/repos/auth0/blog/hooks","issue_events_url":"https://api.github.com/repos/auth0/blog/issues/events{/number}","events_url":"https://api.github.com/repos/auth0/blog/events","assignees_url":"https://api.github.com/repos/auth0/blog/assignees{/user}","branches_url":"https://api.github.com/repos/auth0/blog/branches{/branch}","tags_url":"https://api.github.com/repos/auth0/blog/tags","blobs_url":"https://api.github.com/repos/auth0/blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/auth0/blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/auth0/blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/auth0/blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/auth0/blog/statuses/{sha}","languages_url":"https://api.github.com/repos/auth0/blog/languages","stargazers_url":"https://api.github.com/repos/auth0/blog/stargazers","contributors_url":"https://api.github.com/repos/auth0/blog/contributors","subscribers_url":"https://api.github.com/repos/auth0/blog/subscribers","subscription_url":"https://api.github.com/repos/auth0/blog/subscription","commits_url":"https://api.github.com/repos/auth0/blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/auth0/blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/auth0/blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/auth0/blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/auth0/blog/contents/{+path}","compare_url":"https://api.github.com/repos/auth0/blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/auth0/blog/merges","archive_url":"https://api.github.com/repos/auth0/blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/auth0/blog/downloads","issues_url":"https://api.github.com/repos/auth0/blog/issues{/number}","pulls_url":"https://api.github.com/repos/auth0/blog/pulls{/number}","milestones_url":"https://api.github.com/repos/auth0/blog/milestones{/number}","notifications_url":"https://api.github.com/repos/auth0/blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/auth0/blog/labels{/name}","releases_url":"https://api.github.com/repos/auth0/blog/releases{/id}","deployments_url":"https://api.github.com/repos/auth0/blog/deployments","created_at":"2013-01-25T22:57:37Z","updated_at":"2017-11-15T01:55:12Z","pushed_at":"2017-12-05T20:44:21Z","git_url":"git://github.com/auth0/blog.git","ssh_url":"git@github.com:auth0/blog.git","clone_url":"https://github.com/auth0/blog.git","svn_url":"https://github.com/auth0/blog","homepage":"https://auth0.com/blog","size":21769,"stargazers_count":47,"watchers_count":47,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":95,"mirror_url":null,"archived":false,"open_issues_count":48,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":95,"open_issues":48,"watchers":47,"default_branch":"master"}},"base":{"label":"auth0:master","ref":"master","sha":"22b99b7f4e736f0972764bce59c723baa6d60844","user":{"login":"auth0","id":2824157,"avatar_url":"https://avatars1.githubusercontent.com/u/2824157?v=4","gravatar_id":"","url":"https://api.github.com/users/auth0","html_url":"https://github.com/auth0","followers_url":"https://api.github.com/users/auth0/followers","following_url":"https://api.github.com/users/auth0/following{/other_user}","gists_url":"https://api.github.com/users/auth0/gists{/gist_id}","starred_url":"https://api.github.com/users/auth0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auth0/subscriptions","organizations_url":"https://api.github.com/users/auth0/orgs","repos_url":"https://api.github.com/users/auth0/repos","events_url":"https://api.github.com/users/auth0/events{/privacy}","received_events_url":"https://api.github.com/users/auth0/received_events","type":"Organization","site_admin":false},"repo":{"id":7830124,"name":"blog","full_name":"auth0/blog","owner":{"login":"auth0","id":2824157,"avatar_url":"https://avatars1.githubusercontent.com/u/2824157?v=4","gravatar_id":"","url":"https://api.github.com/users/auth0","html_url":"https://github.com/auth0","followers_url":"https://api.github.com/users/auth0/followers","following_url":"https://api.github.com/users/auth0/following{/other_user}","gists_url":"https://api.github.com/users/auth0/gists{/gist_id}","starred_url":"https://api.github.com/users/auth0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auth0/subscriptions","organizations_url":"https://api.github.com/users/auth0/orgs","repos_url":"https://api.github.com/users/auth0/repos","events_url":"https://api.github.com/users/auth0/events{/privacy}","received_events_url":"https://api.github.com/users/auth0/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/auth0/blog","description":"auth0 blog","fork":false,"url":"https://api.github.com/repos/auth0/blog","forks_url":"https://api.github.com/repos/auth0/blog/forks","keys_url":"https://api.github.com/repos/auth0/blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/auth0/blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/auth0/blog/teams","hooks_url":"https://api.github.com/repos/auth0/blog/hooks","issue_events_url":"https://api.github.com/repos/auth0/blog/issues/events{/number}","events_url":"https://api.github.com/repos/auth0/blog/events","assignees_url":"https://api.github.com/repos/auth0/blog/assignees{/user}","branches_url":"https://api.github.com/repos/auth0/blog/branches{/branch}","tags_url":"https://api.github.com/repos/auth0/blog/tags","blobs_url":"https://api.github.com/repos/auth0/blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/auth0/blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/auth0/blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/auth0/blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/auth0/blog/statuses/{sha}","languages_url":"https://api.github.com/repos/auth0/blog/languages","stargazers_url":"https://api.github.com/repos/auth0/blog/stargazers","contributors_url":"https://api.github.com/repos/auth0/blog/contributors","subscribers_url":"https://api.github.com/repos/auth0/blog/subscribers","subscription_url":"https://api.github.com/repos/auth0/blog/subscription","commits_url":"https://api.github.com/repos/auth0/blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/auth0/blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/auth0/blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/auth0/blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/auth0/blog/contents/{+path}","compare_url":"https://api.github.com/repos/auth0/blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/auth0/blog/merges","archive_url":"https://api.github.com/repos/auth0/blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/auth0/blog/downloads","issues_url":"https://api.github.com/repos/auth0/blog/issues{/number}","pulls_url":"https://api.github.com/repos/auth0/blog/pulls{/number}","milestones_url":"https://api.github.com/repos/auth0/blog/milestones{/number}","notifications_url":"https://api.github.com/repos/auth0/blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/auth0/blog/labels{/name}","releases_url":"https://api.github.com/repos/auth0/blog/releases{/id}","deployments_url":"https://api.github.com/repos/auth0/blog/deployments","created_at":"2013-01-25T22:57:37Z","updated_at":"2017-11-15T01:55:12Z","pushed_at":"2017-12-05T20:44:21Z","git_url":"git://github.com/auth0/blog.git","ssh_url":"git@github.com:auth0/blog.git","clone_url":"https://github.com/auth0/blog.git","svn_url":"https://github.com/auth0/blog","homepage":"https://auth0.com/blog","size":21769,"stargazers_count":47,"watchers_count":47,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":95,"mirror_url":null,"archived":false,"open_issues_count":48,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":95,"open_issues":48,"watchers":47,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/auth0/blog/pulls/1203"},"html":{"href":"https://github.com/auth0/blog/pull/1203"},"issue":{"href":"https://api.github.com/repos/auth0/blog/issues/1203"},"comments":{"href":"https://api.github.com/repos/auth0/blog/issues/1203/comments"},"review_comments":{"href":"https://api.github.com/repos/auth0/blog/pulls/1203/comments"},"review_comment":{"href":"https://api.github.com/repos/auth0/blog/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/auth0/blog/pulls/1203/commits"},"statuses":{"href":"https://api.github.com/repos/auth0/blog/statuses/d4f38ea5a0d9b18dbca308ece4c740c4580a1e22"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"tjanczuk"}}