Hacker Newsnew | past | comments | ask | show | jobs | submit | cainlevy's commentslogin

Seems like an oversight, doesn't it? I've created an issue to track here: https://github.com/keratin/authn-server/issues/15


Fixed, thanks!


no problem, btw, the first time I did make test I got this, but after that I was not able to repro it again and make test always worked, pasting here in case you are interested

    Creating authnserver_server_1 ... done
    TEST_REDIS_URL=redis://127.0.0.1:8701/12 \
      TEST_MYSQL_URL=mysql://root@127.0.0.1:8702/authnservertest \
      go test ./data/... ./models/... ./tokens/... ./ops/... ./config/... ./lib/... ./api/... ./services/... .
    [mysql] 2017/11/08 13:27:23 packets.go:33: unexpected EOF
    [mysql] 2017/11/08 13:27:23 packets.go:33: unexpected EOF
    [mysql] 2017/11/08 13:27:23 packets.go:33: unexpected EOF
    --- FAIL: TestAccountStore (0.01s)
        --- FAIL: TestAccountStore/MySQL (0.00s)
            Error Trace:    account_store_test.go:43
        	Error:		Received unexpected error driver: bad connection
        			Connect
        			github.com/keratin/authn-server/data/mysql.ensureDB
        				/home/luser/go/external/src/github.com/keratin/authn-server/data/mysql/db.go:71
        			github.com/keratin/authn-server/data/mysql.TestDB
        				/home/luser/go/external/src/github.com/keratin/authn-server/data/mysql/db.go:27
        			github.com/keratin/authn-server/data_test.TestAccountStore.func3
        				/home/luser/go/external/src/github.com/keratin/authn-server/data/account_store_test.go:42
        			testing.tRunner
        				/usr/local/stow/go-1.9.0/go/src/testing/testing.go:746
        			runtime.goexit
        				/usr/local/stow/go-1.9.0/go/src/runtime/asm_amd64.s:2337
        			ensureDB
        			github.com/keratin/authn-server/data/mysql.TestDB
        				/home/luser/go/external/src/github.com/keratin/authn-server/data/mysql/db.go:29
        			github.com/keratin/authn-server/data_test.TestAccountStore.func3
        				/home/luser/go/external/src/github.com/keratin/authn-server/data/account_store_test.go:42
        			testing.tRunner
        				/usr/local/stow/go-1.9.0/go/src/testing/testing.go:746
        			runtime.goexit
        				/usr/local/stow/go-1.9.0/go/src/runtime/asm_amd64.s:2337
        		
    FAIL
    FAIL	github.com/keratin/authn-server/data	0.040s
    ?   	github.com/keratin/authn-server/data/mock	[no test files]
    ?   	github.com/keratin/authn-server/data/mysql	[no test files]
    ok  	github.com/keratin/authn-server/data/redis	0.771s
    ?   	github.com/keratin/authn-server/data/sqlite3	[no test files]


Thanks for the report! I believe I've tracked this down to an initialization routine that MySQL goes through on the first boot. It happens after docker-compose unblocks. Likely a wontfix. :/


cool you found the root cause, I take this is not the code path that runs in CI? otherwise I'd think you'd hit it all the time unless somehow the MySQL container sticks around...


Yeah. I think Travis provides a warmed server.


Thanks!

Have you seen the /stats endpoint? It exposes the metrics as JSON, which may be a good match for your suggestion. I'd also like to export the key events to a STATSD-compatible sink so a sophisticated user can manage metrics in their own system.

Redis is already on hand because of other features though, and HLL is a pretty cheap integration. I figure it's a decent starting point for many people.


It looks like the /stats endpoint consults the Redis database and returns processed data. If we're aggregating metrics externally, it would be more idiomatic for this to be totally stateless and just expose hot metrics - it's the aggregator's job to store and process the data. This can be quite painless using something like the Go Prometheus library.

Being tied to Redis is also not great. For instance, it looks like everything apart from the metrics could comfortably live in Google Cloud Storage if you had a backend for it. Cloud Storage really isn't an appropriate place to put frequently updated counters, though. So if I deployed AuthN, I would want to be able to ditch Redis.

I should stress, though, that these are quibbles. I think AuthN looks very nice, and the quibbles are cropping up because I'm trying to figure out if I can use it. :)


That all sounds like a direction I'd happily consider:

* Google Cloud Storage implementations for data interfaces

* Metrics interface with a Prometheus implementation (STATSD to follow)

* Redis-backed HLL metrics are optional

Feel free to open issues in the tracker if you reach that point!


Good stuff.

I have one other bit of feedback on the architecture, and I realise that this one might be too different from where AuthN is currently. I see that there are a small number of API endpoints that you've marked "public" that users are meant to be able to reach. In practice, the user's POSTs would always be terminated upstream from the AuthN server itself, either at a gateway or by just relaying the requests through from the front-end servers themselves. A service that's part public/part private is much more perilous than a service that is one or the other. All things considered, these public endpoints seem like a very minor convenience to the integrator. I would just make the AuthN API private, and ask users to implement the public endpoints themselves by making requests to the AuthN API.

If you DID make all endpoints private, you're no longer tied to HTTP, and you have a nice opportunity to use GRPC instead. I've recently started rolling it out in my own services, and it's unexpectedly great considering the track-record of similar ideas. It's very performant, pleasant to work with, has a mature ecosystem of surrounding tools, and you get client API implementations in a wide range of languages for "free" (or at least at a cut price).


My intention for the user-facing endpoints is that the host app will never need to see or accidentally log a user's password. It's a pattern inspired by credit card vaults.

Could you still achieve your deployment goals with a Gateway/WAF setup that proxies the user-facing endpoints? The only issue I'm presently aware of with this setup is https://github.com/keratin/authn-server/issues/8.


Sure - in my case this would be a load balancer on Google Cloud configured through a Kubernetes ingress. All the public paths available on the Auth microservice would have to be listed explicitly. You have to be very sure in this scenario that only the public URLs are reachable.

I see the motivation for sending user passwords straight to AuthN, but I do wonder if on balance the dangers of correctly configuring a shared public/private service don't outweigh the dangers of relaying the password through your front-end (which has to be able to access private endpoints on the AuthN service anyway). If you really didn't want your front-end to touch passwords, you could have a tiny sidecar service that only exposes the public endpoints and speaks GRPC to AuthN.

Anyway, this is well into debatable "matter of opinion" territory, and I don't want to waste your time. Thanks for publishing AuthN - I'll keep a close watch as you progress.


Yep, it's very broad. Let's say it depends how "majestic" a person's monolith is? :D

One point of context I'd like to inject here is that chatter between AuthN and a host app is pretty minimal. Aside from executing admin actions like locking an account, the main dependency is fetching a public key to verify JWTs. This public key can be cached using a standard key fingerprint, which means it only needs to happen once per process.

Architecture does matter, and I've been pretty happy with how AuthN's boundary has played out.


It's on my roadmap. Prioritizing is hard. :/


Keycloak does some really great things. It does require managing a Java runtime though, and is missing the streamlining that allows AuthN to run as an invisible API.

Keycloak (and similar) hosts and renders your login page. You customize through theming. You're expected to redirect users through a standard OAuth2/OIDC flow on a different domain.

AuthN doesn't render any HTML. That's all you, from start to finish. This means you have control over the UX and can build the login page directly into your own app, just like you would when using an auth library in a typical monolith.


What, I can't simply post to any login/register/logout uri's and expect either a redirect with configuring headers back or an object that let's me manage the token manually?

EDIT: I've been trying out keycloak and it looks great but I've always assumed I just had not figured out how to make that happen. As the documentation is quite large and of the harder kind.


You can design the login/register page in keycloak completely. From scratch. I have used it before and had done that.


Yeah, I don't expect this JWT scheme to become an adopted standard. It's been streamlined from OIC for the narrow use case of working tightly with a trusted app.

Adding support for inbound federation is on the roadmap. Support for outbound federation using OIC isn't out of the question either, but I don't yet see the motivation.


Yeah, name/pass sounds pretty simple, doesn't it? But doing it correctly, securely, with a service architecture? That gets interesting.

> It would be much more interesting to me if it also did Oauth2 login with Google/Facebook/Twitter/etc.

Totally agreed. The reason I designed AuthN around accounts first is because I believe that's the best way to launch an app. OAuth2 and OIC logins are powerful, but they're secondary to the classic login.


Tests are colocated inside packages (folders) using a `_test.go` convention.

Service tests[1] are the main unit tests, and use mock implementations of the data store interfaces.

Data (DAO) tests[2] are generally run across every implementation using only the public interface. This helps me stay sane with the mock implementations.

The API tests[3] are integration tests, and use Go's excellent httptest package to boot a real server and execute real HTTP commands.

[1] https://github.com/keratin/authn-server/tree/master/services

[2] https://github.com/keratin/authn-server/tree/master/data

[3] https://github.com/keratin/authn-server/tree/master/api/acco...


Strong choice! My dream is for AuthN to provide authentication and account functionality for folks who have not yet invested in an API gateway, and then seamlessly plug in when their architecture matures later. Extracting user accounts can be a difficult barrier for transitions like that.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: