-
ALAN COHEN: OK. Can everyone hear me? Raise
your hand if,
-
yeah? Cool. This is my first talk, so I'm
a little bit
-
nervous. I'm gonna, actually, take a picture
for my mom.
-
So, if everyone can, like, wave. Awesome.
Yes. All right.
-
All right. Cool. So, my talk is about authorization.
-
Service-oriented authorization. My name is
Alan, by the way.
-
You can find me on Twitter and GitHub.
-
I work at a company called The Climate Corporation.
-
I'm a Ruby developer there. I've been there
for
-
about a year and a half working on, we
-
have an insurance product, I work on the backend
-
as well as other parts of our web infrastructure.
-
We have products that help protect farmers
from weather
-
disasters and improve their farming operations
during the planting
-
and, before and after the planting season.
It's sort
-
of like, if I'm gonna make it, like, buzz-word
-
compliant, it's big data farming.
-
So, a little bit of background before I get
-
into my talk. What is authorization? So, if
you
-
were in this room before, you probably learned
about
-
authentication in a service, service-oriented
environment. Today I'm talking
-
authorization. So, authentication is concerned
with identity. Authorization is
-
concerned with access.
-
There are different types of authorization.
If you've ever
-
implemented it. You can think about role-based
access control,
-
attribute-based access control, access control
lists, rule-based access control.
-
It can go on and on. I'm not talking
-
about a specific implementation of authorization,
but just, in
-
general, right.
-
What is service oriented architecture? Right.
There's been many,
-
many talks. I think this entire track is on
-
service oriented architecture. And, you know,
there's been talks
-
yesterday. I've gone to a few of these talks.
-
I, they, service oriented architecture is
many different solutions
-
to different problems. But, you know, it's
around the
-
same theme, I guess.
-
This, where I'm not talking about a specific
implementation
-
of SOA, so I want to find a really
-
basic definition of it, and I found this.
A
-
loosely-coupled architecture designed to meet
the business needs of
-
an organization. I found this on the Microsoft
Developer
-
Network site. And it also had this, like,
really
-
interesting quote. And it started with, SOAs
are like
-
snowflakes. No two are alike.
-
But I wanted to find like a, a better
-
definition. And actually, when I was watching
Brian Morton's
-
talk from Big Rails, Big Ruby last year, Rails,
-
Services and Rails, The Shit They Don't Tell
You.
-
He says, Components that scale individually.
That's sort of
-
how he defines service oriented architecture.
-
And I, I recommend that talk, if you want
-
to learn about implementing service oriented
architecture. Some services
-
oriented architecture, from someone who has
the battle scars
-
moving over to something like that. But today,
I'm
-
not, I'm not, like, focusing on what it is.
-
So, why talk about it? Right. Why, why services
-
oriented architecture? We have to und- you
know, before
-
we get into authorization, I want to talk
a
-
little bit about why we would use SOA. SOA
-
gives us a lot of things, right. Reusability,
we
-
can allocate resources as we need them, loose
coupling,
-
we can change out libraries, a codebase that
scales
-
across teams and so, we get, we get things
-
that are good for both our software and for
-
our software development process.
-
There are a lot of problems, also, right,
that
-
you have to solve when you have a service
-
oriented architecture. Right, services speaking
to one another. Like,
-
a lot of things become difficult. But hopefully
you're
-
here because the, the benefits of SOA outweigh
the
-
problems that you might have. And you've already
sort
-
of made that decision. I'm not gonna try to
-
sell you on it.
-
So, what is service oriented authorization?
Well, if we
-
think about the benefits of services oriented
architecture, it
-
should be sort of parallel to that. Reusability,
I
-
want to be able to use the, the same
-
authorization tools, libraries, code, across
multiple services. Loose coupling.
-
My application code is not coupled to my authorization
-
implementation. And then, lastly, scalability.
So, this is like
-
a requirement when you have multiple services.
And this
-
is just gonna be like a general requirement
when
-
we talk about, like, the framework that I
want
-
to use.
-
So, let's imagine a typical Rails application,
ignoring things
-
like the database and other third-party services.
You have
-
your, you have Rails, you have your business
logic,
-
and then you have some third-party gems that
you
-
might use.
-
The important part is your business logic,
right. That's,
-
like, if you have an online product, like
BaseCamp,
-
right, that's the interesting stuff. That's
the part that's
-
gonna make you money. It's what, why your
cosumer's
-
pay you money. Everything else is just there
to
-
help you deliver that product.
-
I think authorization can be thought of as
part
-
of your business. Whether it's part of the
security
-
of your application, for example, like, you
have employees
-
that, only your employees are allowed to administer
customer
-
data, like, for customer support. Or, whether
it's part
-
of the feature of your application. Like,
in BaseCamp,
-
you have, like admin users in different groups.
-
So, what does authorization look like today?
I think,
-
you know, the most popular authorization library
is -
-
I don't know if you can see this -
-
but, this is like a snapshot of CanCan's GitHub's
-
page. I think it's probably the most popular
authorization
-
gem. We use it in production. It works. It's
-
historically been well-supported. I think
it's still pretty good.
-
But, you know, it gives you, like, a really
-
nice declarative DSL for specifying rules,
like, so then,
-
you specify your rules, like, within your
application, and
-
it's, like, nice Ruby DSL. And then you can
-
ask questions like, can a user manage this
other
-
user's data. Can a user purchase a policy,
if
-
you're selling insurance.
-
But the question is, does this approach align
with
-
what we've defined as service oriented authorization?
Right. CanCan
-
is reusable, right, because it's a library.
So, you
-
know, the authorization implementation is
decoupled from our app.
-
We don't, like, bake authorization into our
app.
-
But it's, it's not really loosely coupled,
right. If
-
you think about it, your authorization rules
are, are
-
embedded in your application code, right.
So like, the,
-
the. What is it? Yeah. The, your rules are
-
in your application. And there's some limitations
to this
-
approach, which aren't apparent at first,
right.
-
And, so what? Like, what are those limitations?
Or,
-
why does that matter? Well, I think that if
-
we want to keep the core of our application
-
small and understandable as possible, we want
to, we
-
want to do that because that's the part that
-
makes us money. The business logic is what's
important.
-
And it's the part we want to keep free
-
of bugs. If we, if we do that, we
-
can develop with confidence, like we know
we won't
-
develop and create bugs. Our business logic
is concerned
-
with authorization only as far as we need
to
-
make sure to enforce it. But we shouldn't
care
-
about how it's implemented, but just that
it works.
-
So, this is your business logic. This is you
-
enforcing authorization in your code. But
the rest is,
-
I think, can, should be thought of as implementation
-
details, right. Where you define those rules.
It doesn't
-
necessarily need to be part of your system.
It
-
needs to exist somewhere.
-
And I'll explain why, why that matters, right.
So,
-
in a services oriented architecture, right,
you usually start
-
with a monolithic application. And if we've
coupled our
-
rules to our application, then it's gonna
be very
-
difficult to split things into services, right.
Especially if
-
there, all these services are concerned with
a user.
-
You have all these user rules in your, in
-
your monoRails app, but now they sort of have
-
to be broken out. And that's fine if you're
-
gonna use, right, CanCan across these different
Ruby or
-
Rails applications. But a services oriented
architecture usually, by
-
default, means you're gonna have, like, a
heterogenous environment.
-
And this is actually very similar to what
we
-
have in production today, where we don't just
have
-
the Rails stack. We have other, other things,
either
-
in Java or Clojure or whatever it might be
-
in the future. And, there really isn't an
easy
-
way to go from CanCan to Clojure, right.
-
So, we want to, we want to think about
-
a different framework to, to basically do
this. So,
-
what are the goals of whatever approach we
take?
-
Well, the goal, goals, you know, restating
them. Reusability,
-
scalability, and loose coupling.
-
So, let's go back to our app, right. We
-
have the same Rails app, but it's, it's very
-
simplified. Your app, when you move it onto
different
-
services, might look like this, where you
have different
-
JavaScript frontends that are, you know, we
deploy them
-
as different modules. Our users like see a
single
-
interface, but really it's several different,
several different applications
-
that are speaking to several different backends.
-
And the business logic that used to reside
in
-
a single application now is residing across
multiple applications,
-
and those, yeah. So, the, the key take away
-
is that this is a heterogenous environment,
and so
-
we shouldn't constrain ourselves, right, by
language or run
-
time. We want to use the best possible tools
-
to, to grow our services, to build them.
-
So, reusability means we want code that doesn't
require
-
us to predict the future. And, if I'm gonna
-
extract my authorization into another service
or, part of
-
my authorization into a separate service,
like, I need,
-
I need to be able to do that without,
-
without having to rewrite it. I don't want
to
-
have to rewrite everything.
-
And that's, loose coupling means, like, that,
we, we're
-
gonna decouple the access decision from the
access policy.
-
So, just, restating, restating that, we can't
use this,
-
right, outside of a, outside of our Rails
application.
-
We also need whatever framework to be scalable.
So,
-
there's, you know, when I was researching
this and
-
I was like, what are, what are the available
-
tools to be able to do something like this?
-
And I didn't really find anything. I did find,
-
of this, of this thing called XACML. I mean,
-
raise your hand if you've heard of XACML.
-
Yeah. So I see, like, maybe ten people have
-
raised your hand. So XACML is, it's XML, and
-
it stands for extensible access control markup
language. And
-
it's a declarative policy language implemented
in XML. And
-
it defines a processing model that describes
how to
-
evaluate access requests according to rules
defined and policies.
-
So it actually, if you read the spec it's,
-
I think like hundreds of pages long, and it
-
actually defines an entire architecture using
XML to define
-
authorization rules and sort of like, all
these different
-
services to implement authorization. And that,
in fact, it
-
uses a centralized authorization service,
and it's pretty, it's
-
pretty complex, I think.
-
But, I found this from a spec, and I
-
thought this was actually really poignant.
The XACML model
-
supports and encourages the separation of
the access decision
-
from the point of use.
-
When access decisions are baked into client
applications, it
-
is very difficult to update the decision criteria
when
-
the governing policy changes. When the client
is decoupled
-
from the access decision, authorization policies
can be updated
-
on the fly and affect all clients immediately.
-
So, this is what an XACML policy would look
-
like. I got the indenting wrong, but, I mean,
-
you get the idea. It's, it's pretty complex,
but
-
it gives us this advantage of being able to
-
update and modify the rules without touching
our application
-
code, and so it should, we should be able
-
to use this in sort of a hit, in
-
a heterogenous environment. As long as we
have some
-
authorization library that we can use within
our application.
-
But, I thought that this is, this is, like,
-
way too much for, for what we needed, right.
-
Like, we, like, we don't have thousands and
thousands
-
of rules. Our application is actually fairly
simple compared
-
to the implementations I've seen for this.
So, I
-
wanted to, to, you know, try something a little
-
bit simpler, right.
-
Thing is, I didn't, I didn't really find anything
-
simpler. So, when, when we were discussing
this authorization
-
framework that I'm gonna go over, we, we thought,
-
like, all right, let's, let's come up with
a
-
very simple language that we can use and,
you
-
know, as we, as we build this out, as
-
we test it, we can, we can experiment with
-
it, and if we need to bake more features
-
into it, let's do that. But let's, let's,
let's
-
implement as few features as we need as possible.
-
And, so that's where we started.
-
So, just a recap: we talked a little bit
-
about why would we choose SOA architecture.
What SOA
-
might be. And we set our goals to be
-
scalability, flexibility, and loose coupling.
And we talked about
-
why we chose these three goals. Like, what
are
-
their benefits.
-
So, what, like, what did we come up with?
-
And, I guess, I didn't, I didn't really talk
-
about, like, what this is. What this framework
is.
-
But, you know, I worked, I worked with a
-
few guys in my company. We said all right.
-
Let's, let's build this, it's, it's not really
a
-
framework. It's more like let's, let's define
a language
-
where we can, we can define authorization
policies, and
-
it's really, it's agnostic to, to Rails, whatever
it
-
is, and let's, let's try to create, like,
a
-
reference implementation and experiment with
it. And then see
-
if it's, if this is a rich enough language
-
to be able to use and replace whatever we
-
have today.
-
So, this is, this is sort of, like, this
-
is the like, the v zero dot one alpha
-
of the language, right. We don't, there's
not like
-
an official spec that we, you know, we have
-
a very, like, early spec for this, and this
-
is sort of like what we came up with.
-
And I'll go through, like, each, each object
in
-
this, in this, in this JSON. So, we have
-
a resource. A resource could be defined within
a
-
namespace, and so it could also be like, just
-
the name of a class. So like, if it's
-
a Rails application, it could be like an ActiveRecord
-
model. An action, or a set of actions. So,
-
a rule will apply to a set of actions,
-
just like in CanCan, you sort of do the
-
same thing.
-
You have a set of conditions that define the
-
evaluation context of a rule. So, whether
a rule
-
applies or not. So, in this case, this is
-
like, how we would say, like, the, the role
-
of a user must equal admin. So, if we're,
-
right.
-
And then every rule will have an effect. So
-
it'll be either allow or deny. So we have
-
this language. But, something is missing.
And that's, what's
-
sort of bridging that gap, right. We have
an
-
application. Now we have a set of rules. Like,
-
what's, what's connecting the two?
-
And so, right, I wrote this really small gem,
-
and it's called IronHide. And, we just have
this
-
practice of naming all of our gems at work
-
after Transformer characters. So, IronHide
is this, is sort
-
of this bridge. We define a set of rules,
-
and we have our application, and then we include
-
IronHide into our application, and IronHide
exposes the same
-
API that CanCan would, and so it's sort of
-
like a drop-in.
-
And, so like, what is it? It's not a
-
service. It doesn't provide an authorization
service for us.
-
It's actually just a library. So, that, that's
an
-
important distinction, because we're, you
know, where are the
-
rules, right? If it's not a service, then
it's
-
gonna have to call out and get the rules
-
from somewhere.
-
And that's, that's actually pretty cool, because
we can
-
store the rules anywhere we want, right. They're
just,
-
it's just JSON. So, JSON can really be stored
-
anywhere. It can be stored, like, on, on disc.
-
It can be stored in the document store. And
-
having this, like, plugability to different
backend stores gives
-
us scalability.
-
So, does it meet our goals? Right. Reusability,
scalability,
-
loose coupling. The authorization rules are
not part of
-
the application code. The, the language in
which we
-
define the rules is language agnostic. So
it should
-
be reusable across, across environments. And,
if we've decoupled
-
the backing store from the authorization implementation,
then it
-
should be as scalable as we want it to
-
be.
-
So, today, it's still a work in progress.
It's
-
still something that we're experimenting with,
right. You know.
-
XACML is like, it's a very well-defined spec.
I
-
think it's like version three point 0 of the
-
spec. It's, it's sort of like an enterprise-level
design.
-
This is like, you know, we're experimenting
with it.
-
You know. Could it scale to thousands and
thousands
-
of rules and to like, many, many services?
I
-
don't know yet. Right.
-
It's not yet in production. But, and it's
also
-
something that, you know, we need to standardize
and
-
name the policy language. Right. There's no
name for
-
it. Like, so. I'd like to actually do a
-
demo. So. Let's see if this works.
-
Where is this? Can everyone see that? No.
If
-
I make the. Too small?
-
AUDIENCE: We can't see the font.
-
A.C.: Can't see-? Oh, yeah. Would it, would
it
-
be better if I made the background light and
-
the foreground dark?
-
AUDIENCE: No.
-
A.C.: No. OK. Right. So, so this is, like,
-
this is a rule, right. It's, and it's, and
-
this is, and I've written this just directly
into
-
a flat file on my disc. So there's some
-
resource under this app namespace, a set of
actions.
-
An effect and a set of conditions.
-
And then, I actually made, like, a really
simple
-
-it's not an app. It's just. I created a
-
user class. It has a manager id and an
-
id. And if you look at the, right, if
-
you look at the rule, I'm saying that a
-
user, it's allowed to read or manage another
user.
-
In this case, the resource is also a user.
-
So, we're always authorizing against the
user. So, the
-
user is allowed to do something to another
thing.
-
And in this case it's another user.
-
As long as the user's id is equal to
-
the other thing's manager id. So, here, we
have
-
a user with a manager. I'm gonna run this
-
and then jump directly into the console, so
I
-
can, like, start writing code.
-
Oh. OK. So, right. I can, I can. Let's
-
see. User. Right. So, this. This user has
a
-
manager id now that's equal to the manager's
id.
-
And then. I didn't, I didn't really go into
-
depth, into the IronHide, like, library, but
I'm gonna
-
post a link to the source. I've tried to
-
write a pretty well-documented README.
-
So, it should be fairly self-explanatory.
Basically, there's a,
-
a configuration. Oh. Crap.
-
OK. And then. So. It's like. It works.
-
AUDIENCE: [laughter - applause]
-
A.C.: Yeah. It's actually kind of funny, cause
I
-
tried recording this, and it was probably
easier doing
-
it live. I'm gonna try to jump back.
-
So. So yeah. These, these are links to the
-
source, so that's like. I tried getting a
short
-
link for the GitHub page. And there's actually
a
-
sample app with, sort of like, what, it was
-
sort of like that, maybe with a few, a
-
few additional things. And I also wrote, like,
an
-
adapter that would let you use, like, CouchDB
as
-
the backing store for the rules.
-
CouchDB's pretty cool. So. It was the first
time
-
I used it.
-
OK.
-
AUDIENCE: [applause]