On Sun, 2015-02-22 at 21:18 -0800, Eric Sorenson wrote: > > > On Feb 16, 2015, at 2:01 AM, Brice Figureau > > <brice-pup...@daysofwonder.com> wrote: > > > > Hi, > > > > Following a conversation I had with Kevin and Deepak at last Ghent > > Contributor summit about solving SERVER-111[*], I started working on > > a > > clojure port of the Puppet authorization system (since I wrote a > > large > > part of it, I felt I was kind of best placed to start this). > > > > For the moment all the code is hosted in its own project on my > > github > > account (because that was simpler than abusing another trapperkeeper > > project as a PR for repeated development): > > https://github.com/masterzen/trapperkeeper-authorization > > > > It's a work in progress with only the following working basic > > functionalities at the moment: > > * various ip, host, wildcard, regex, opaque, backreference > > authorization > > entries creation/matching (ACE) > > * authorization entry list (ACL) creation and matching > > > > All those features should be fully compatible with the way Puppet > > authorization system works. > > > > > Hi Brice! This project is really cool, thanks for taking it on. I have > a few comments about requirements and design that I hope can save some > work and make it easier to include this upstream once it's done. > > > I went back and surveyed redmine, jira, and ask.pl.com for bugs around > auth.conf to see what people have run into over the years > ( https://www.google.com/search?q=site%3Apuppetlabs.com > +auth.conf&gws_rd=ssl ), and from those results plus recalling > conversations with #puppet there seem to be a few general categories > that we should examine when designing a replacement > > > First, I don't think you need to try to make it compatible with the > existing auth.conf format. It'd be good to take the opportunity to > move to a structured data format that is easier to read and write > programmatically, which addresses issues like Branan's > PR https://github.com/puppetlabs/puppet/pull/1353 where the goal was > to have different parts of the module codebase manage snippets of > auth.conf. > > > Second, the main UX problem w/ auth.conf seems to be difficulty > tracking down why a particular request is being denied. I think this > has improved over time but I know it's incredibly frustrating to just > get the 403 error on the client and not be able to check the master's > logs to see why each set of 'permit' rules was not allowed. So it'd be > awesome to start out with easy discoverability/debugging as first > class objectives. > > > (Meta-question: are we sure there's not an existing model -- either a > reusable codebase or simply a config syntax -- that we can use > directly, rather than reinventing a wheel? The ones I'm most familiar > with are apache mod_access and Netscaler content-switching rules, > which aren't great examples, but surely this problem has arisen > before.) > > > Last, as a quick summary of some functional requirements, I'd like > make sure an implementation: > - doesn't rely on puppet-specific paths and could be re-used across > other services like puppetdb (auth.conf has some implicit magic > because IIRC the rules do not see the environment part of the path) > - had clearer semantics around authorizing IPs vs certificates (just > aesthetically, the regexp backreferences from auth rules back into > path matching are not my favorite) and addresses PUP-1562 > - resolves the confusion about access control in fileserver.conf > overlapping with auth.conf (see PUP-1237) > - ... i think that's all :) > > > I'd welcome some conversation on these items or additional ones if > anyone on the list feels like chiming in. None of it is not set in > stone but I would definitely like to build up set of design > requirements and acceptance criteria for the implementation before you > spend a ton of time on it.
I think I've completed a milestone in respect with what you wanted and SERVER-111: https://github.com/masterzen/trapperkeeper-authorization I've tried to put the better documentation I could in the project README, but I think that's not where I shine. So let me summarize what this library does. The aim is to provide an authorization layer that could be used in the Puppetlabs JVM projects. For this the library offers two components: * a DSL to build authorization rules (either internal or from a HOCON file, auth.conf not yet supported) * a ring middleware that can be added to a compojure app, checking incoming request against the authorization rules. Authorization rules is a list (in insertion order) of independent rule. A rule is: * an endpoint (either a complete request path-info, or expressed as a regex) * optionnally a restricting HTTP method * an ACL And ACL is a list of access control entry, which are fully compatible with the existing Puppet system (the rationale is that this system seems to work, and most of the people in the ecosystem at least know it a bit, so why design a different system?). There can be several access control entries, each supporting either allowing/denying based on the incoming request certificate CN part of the subject DN, or the remote peer IP address. * allow and allow-ip * deny and deny-ip At the end of the ACL, we have an implicit 'deny all' rule. Allow and deny support the following: * exact names: 'www.domain.org' * wildcard names: '*.domain.org' * regex names: '(this|that).domain.org' * backreference names: '$1.domain.org' * opaque names (same definition as for current Puppet version) Allow-ip and deny-ip support the following: * exact IPv4 or IPv6: '192.168.0.1' or '::1' * network IPv4 or IPv6: '192.168.0.0/24' * wildcard: '192.168.*' When an incoming request ends up in the ring middleware, the request URI is matched against the rules (in order), if none matches the request is denied (implicit deny *), if one matches, its ACL is checked. If the ACL allows the request, the rest of the ring handler are executed, otherwise a 401 is returned with a message telling which rule triggered (and where it was loaded from). So to build rules, the most straightforward system is use the HOCON support: # rules.conf rules = [ { path: /path/to/resource type: path allow: [ "*.domain.org", "*.test.com" ] allow-ip: "192.168.0.0/24" deny: "bad.guy.com" deny-ip: "192.168.1.0/24" }, { type: regex path: "(incoming|outgoing)" allow: "www.domain.org" } ] Then in the project to use those rules: (ns test (:require [puppetlabs.trapperkeeper.authorization.rules :as rules] [puppetlabs.trapperkeeper.authorization.ring-middleware :as ring])) ; loading rules from a file (def rules (rules/config-file->rules "rules.conf")) ; our ring app (def app (-> handler (ring/wrap-authorization-check rules))) So it's quite simple. You can also define rules programatically with a dumb DSL: (def rules (-> rules/empty-rules (rules/add-rule (-> (new-path-rule "/path/to/resource") (allow "*.domain.org"))) (rules/add-rule (-> (new-regex-rule "(this| that)-resource") (allow "$1.domain.org"))))) The code is, I think, quite fully covered by tests. I'd also like to add a few features like deploying to clojars, simplified auth.conf support, Puppet support (ie environment), performance, etc... Now, I'm ready to donate this project to Puppetlabs, if you guys are interested, just let me know how we can achieve the transfer or ownership (well you should first do a thorough code review, since it's my first complete clojure project :). Anyhow, it was a fun project to hack on. Thanks, -- Brice Figureau <brice-pup...@daysofwonder.com> -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/1425891545.27078.22.camel%40arsenic.daysofwonder.com. For more options, visit https://groups.google.com/d/optout.