Hi,

Let me elaborate some more on the purpose of the API GW. I will put up a
wiki page following our discussions here.

Main purpose is to allow innovation by creating new services that handle TO
functionality, not as a part of the monolithic Mojo app.
The long term vision is to de-compose TO into multiple microservices,
allowing new functionality easily added.
Indeed, the goal it to eventually deprecate the current AAA model, and
replace it with the new AAA model currently under work (user-roles,
role-capabilities)

I think that handling authorization in the API layer is a valid approach.
Security wise, I don't see much difference between that, and having each
module access the auth service, as long as the auth service is deployed in
the backend.
Having another proxy (nginx?) fronting the world and forwarding all
requests to the backend GW mitigates the risk for compromising the
authorization service.
However, as mentioned above, we can still have the services check the auth
as well after the proxy auth.

It is a standalone process, completely optional at this point. One can
choose to deploy it in order to allow integration with additional
services. Deployment
and management are still T.B.D, and feedback on this is most welcome.

Regarding token validation and revocation:
Tokens have expiration time. Expired tokens do not pass token validation.
In production, expiration should be set to relatively short time, say 5
minute.
This way revocation is automatic. Re-authentication is handled via refresh
tokens (not implemented yet). Hitting the DB upon every API call cause
congestion on users DB.
To avoid that, we chose to have all user information self-contained inside
the JWT.

Thanks
/amiry

On Mon, May 8, 2017 at 5:42 AM Jan van Doorn <[email protected]> wrote:

> It's the reverse proxy we've discussed for the "micro services" version for
> a while now (as in
> https://cwiki.apache.org/confluence/display/TC/Design+Overview+v3.0).
>
> On Sun, May 7, 2017 at 7:22 PM Eric Friedrich (efriedri) <
> [email protected]>
> wrote:
>
> > From a higher level- what is purpose of the API Gateway?  It seems like
> > there may have been some previous discussions about API Gateway. Are
> there
> > any notes or description that I can catch up on?
> >
> > How will it be deployed? (Is it a standalone service or something that
> > runs inside the experimental Traffic Ops)?
> >
> > Is this new component required or optional?
> >
> > —Eric
> >
> >
> >
> > > On May 7, 2017, at 8:28 PM, Jan van Doorn <[email protected]> wrote:
> > >
> > > I looked into this a year or so ago, and I couldn't make nginx or http
> do
> > > what we need.
> > >
> > > We can still have the services check the auth as well after the proxy
> > auth,
> > > and make things better than today, where we have the same problem that
> if
> > > the TO mojo app is compromised, everything is compromised.
> > >
> > > If we always route to TO, we don't untangle the mess of being dependent
> > on
> > > the monolithic TO for everything. Many services today, and more in the
> > > future really just need a check to see if the user is authorized, and
> > > nothing more.
> > >
> > > On Sun, May 7, 2017 at 11:55 AM Robert Butts <[email protected]
> >
> > > wrote:
> > >
> > >> What are the advantages of these config files, over an existing
> reverse
> > >> proxy, like Nginx or httpd? It's just as much work as configuring and
> > >> deploying an existing product, but more code we have to write and
> > maintain.
> > >> I'm having trouble seeing the advantage.
> > >>
> > >> -1 on auth rules as a part of the proxy. Making a proxy care about
> auth
> > >> violates the Single Responsibility Principle, and further, is a
> security
> > >> risk. It creates unnecessary attack surface. If your proxy app or
> > server is
> > >> compromised, the entire framework is now compromised. An attacker
> could
> > >> simply rewrite the proxy config to make all routes no-auth.
> > >>
> > >> The simple alternative is for the proxy to always route to TO, and TO
> > >> checks the token against the auth service (which may also be proxied),
> > and
> > >> redirects unauthorized requests to a login endpoint (which may also be
> > >> proxied).
> > >>
> > >> The TO service (and any other service that requires auth) MUST hit the
> > >> database (or the auth service, which itself hits the database) to
> verify
> > >> valid tokens' users still have the permissions they did when the token
> > was
> > >> created. Otherwise, it's impossible to revoke tokens, e.g. if an
> > employee
> > >> quits, or an attacker gains a token, or a user changes their password.
> > >>
> > >>
> > >> On Sun, May 7, 2017 at 4:35 AM, Amir Yeshurun <[email protected]>
> wrote:
> > >>
> > >>> Seems that attachments are stripped on this list. Examples pasted
> below
> > >>>
> > >>> *rules.json*
> > >>> [
> > >>>    { "host": "localhost", "path": "/login",               "forward":
> > >>> "localhost:9004", "scheme": "https", "auth": false },
> > >>>    { "host": "localhost", "path": "/api/1.2/innovation/", "forward":
> > >>> "localhost:8004", "scheme": "http",  "auth": true, "routes-file":
> > >>> "innovation.json" },
> > >>>    { "host": "localhost", "path": "/api/1.2/",            "forward":
> > >>> "localhost:3000", "scheme": "http",  "auth": true, "routes-file":
> > >>> "traffic-ops-routes.json" },
> > >>>    { "host": "localhost", "path": "/internal/api/1.2/",   "forward":
> > >>> "localhost:3000", "scheme": "http",  "auth": true, "routes-file":
> > >>> "internal-routes.json" }
> > >>> ]
> > >>>
> > >>> *traffic-ops-routes.json (partial)*
> > >>> .
> > >>> .
> > >>> .
> > >>>    { "match": "/cdns/health",                        "auth": { "GET":
> > >>> ["cdn-health-read"] }},
> > >>>    { "match": "/cdns/capacity",                      "auth": { "GET":
> > >>> ["cdn-health-read"] }},
> > >>>    { "match": "/cdns/usage/overview",                "auth": { "GET":
> > >>> ["cdn-stats-read"] }},
> > >>>    { "match": "/cdns/name/dnsseckeys/generate",      "auth": { "GET":
> > >>> ["cdn-security-keys-read"] }},
> > >>>    { "match": "/cdns/name/[^\/]+/?",                 "auth": { "GET":
> > >>> ["cdn-read"] }},
> > >>>    { "match": "/cdns/name/[^\/]+/sslkeys",           "auth": { "GET":
> > >>> ["cdn-security-keys-read"] }},
> > >>>    { "match": "/cdns/name/[^\/]+/dnsseckeys",        "auth": { "GET":
> > >>> ["cdn-security-keys-read"] }},
> > >>>    { "match": "/cdns/name/[^\/]+/dnsseckeys/delete", "auth": { "GET":
> > >>> ["cdn-security-keys-write"] }},
> > >>>    { "match": "/cdns/[^\/]+/queue_update",           "auth": {
> "POST":
> > >>> ["queue-updates-write"] }},
> > >>>    { "match": "/cdns/[^\/]+/snapshot",               "auth": { "PUT":
> > >>> ["cdn-config-snapshot-write"] }},
> > >>>    { "match": "/cdns/[^\/]+/health",                 "auth": { "GET":
> > >>> ["cdn-health-read"] }},
> > >>>    { "match": "/cdns/[^\/]+/?",                      "auth": { "GET":
> > >>> ["cdn-read"], "PUT":  ["cdn-write"], "PATCH": ["cdn-write"],
> "DELETE":
> > >>> ["cdn-write"] }},
> > >>>    { "match": "/cdns",                               "auth": { "GET":
> > >>> ["cdn-read"], "POST": ["cdn-write"] }},
> > >>>
> > >>> .
> > >>> .
> > >>> .
> > >>>
> > >>>
> > >>> On Sun, May 7, 2017 at 12:39 PM Amir Yeshurun <[email protected]>
> wrote:
> > >>>
> > >>>> Attached please find examples for forwarding rules file (rules.json)
> > >> and
> > >>>> the authorization rules file (traffic-ops-routes.json)
> > >>>>
> > >>>>
> > >>>> On Sun, May 7, 2017 at 10:39 AM Amir Yeshurun <[email protected]>
> > wrote:
> > >>>>
> > >>>>> Hi all,
> > >>>>>
> > >>>>> I am about to submit a PR with a first operational version of the
> API
> > >>> GW,
> > >>>>> to the "experimental" code base.
> > >>>>>
> > >>>>> The API GW forwarding logic is as follow:
> > >>>>>
> > >>>>>   1. Find host to forward the request: Prefix match on the request
> > >> path
> > >>>>>   against a list of forwarding rules. The matched forwarding rule
> > >>> defines the
> > >>>>>   target's host, and the target's *authorization rules*.
> > >>>>>   2. Authorization: Regex match on the request path against a list
> of
> > >>> *authorization
> > >>>>>   rules*. The matched rule defines the required capabilities to
> > >> perform
> > >>>>>   the HTTP method on the route. These capabilities are compared
> > >>> against the
> > >>>>>   user's capabilities in the user's JWT
> > >>>>>
> > >>>>> At this moment, the 2 sets of rules are hard-coded in json files.
> The
> > >>>>> files are provided with the API GW distribution and contain
> > >> definitions
> > >>> for
> > >>>>> TC 2.0 API routes. I have tested parts of the API, however, there
> > >> might
> > >>> be
> > >>>>> mistakes in some of the routes. Please be warned.
> > >>>>>
> > >>>>> Considering manageability and high availability, I am aware that
> > using
> > >>>>> local files for storing the set of authorization rules is inferior
> to
> > >>>>> centralized configuration.
> > >>>>>
> > >>>>> We are considering different approaches for centralized
> > configuration,
> > >>>>> having the following points in mind
> > >>>>>
> > >>>>>   - Microservice world: API GW will front multiple services, not
> only
> > >>>>>   Mojo. It can also front other TC components like Traffic Stats
> and
> > >>> Traffic
> > >>>>>   Monitor. Each service defines its own routes and capabilities.
> Here
> > >>> comes
> > >>>>>   the question of what is the "source of truth" for the route
> > >>> definitions.
> > >>>>>   - Handling private routes. API GW may front non-TC services.
> > >>>>>   - User changes to the AAA scheme. The ability for admin user to
> > >> makes
> > >>>>>   changes in the required capabilities of a route, maybe even
> define
> > >>> new
> > >>>>>   capability names, was raised in the past as a use case that
> should
> > >> be
> > >>>>>   supported.
> > >>>>>   - Easy development and deployment of new services.
> > >>>>>   - Using TO DB for expediency.
> > >>>>>
> > >>>>> I would appreciate any feedback and views on your approach to
> manage
> > >>>>> route definitions.
> > >>>>>
> > >>>>> Thanks
> > >>>>> /amiry
> > >>>>>
> > >>>>
> > >>>
> > >>
> >
> >
>

Reply via email to