-
Notifications
You must be signed in to change notification settings - Fork 371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What Would gorilla/sessions v2 Look Like? #105
Comments
I agree with pretty much all of this. |
Great. I'd also likely simplify gorilla/securecookie as part of this: the internals have grown over time, and moving from the current AES-CTR + MAC approach to either HMAC-SHA-512/256 or ChaCha20+Poly1305 (https://godoc.org/golang.org/x/crypto/chacha20poly1305) and thus simplifying the crypto. securecookie is otherwise a small lib; I think it was a mistake growing the error interface the way we did, but alas. |
+1 for pretty much all of these. You've probably already considered this, but one thing I learnt from building SCS was that although using JSON for the default encoding is sensible from a performance view it has the potential to make things more complicated for users (assuming a For example, retrieving a previously stored Similarly, dealing with integers and floats and You could implement helpers (like I did in SCS), or there's probably something clever that can be done with a custom JSON unmarshaller. Either way, it would be good to keep usage no more difficult than it is with gob encoding. A couple of further suggestions. It would be nice if both absolute and idle timeouts could be supported (in line with the OWASP recommendations). For the non-cookie stores, there would ideally be an clear and baked-in way to renew session IDs after login/logouts etc to help prevent session fixation attacks (possibly as part of the interface along with New, Save etc). At the moment this isn't possible (at least as far as I can see) without a clunky workaround of creating a new session with a different name and copying the data over. |
Thanks for the input @alexedwards -
Yes, agreed. Some
Agree - a |
gorilla/securecookie#43 tracks a "v2" of securecookie that will underpin some of this work |
This looks great. One question: have you considered/what are the tradeoffs of putting included stores with non stdlib imports (cookie, boltdb) into separate packages? Thank you for all your work! |
@ccahoon The stores would each be in separate packages ("sub-packages") so that if you don't use BoltDB, it's not imported. |
Redis, MySQL & Postgres backends already exist, and the Redis store is
rather polished. All of the third party stores are linked in the README.
…On Thu, Mar 23, 2017 at 4:47 PM Kyle Terry ***@***.***> wrote:
Redis and database (sql) support would be cool too. If you are running n
instances of the application using gorilla/sessions you need to be able to
centralize your sessions for round robin.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#105 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABIcDfaPALfkjOw5FzdDoM_MHs9RbCYks5rowSIgaJpZM4LwM5f>
.
|
I think especially supporting the golang context package would be a big step forward. It's even backwards compatible, since all interfaces already accept a request to get the value. Any timeline on this? |
@niondir No timeline. I want to wait until golang/dep hits 1.0 so I existing users have a clear way to pin to pre-2.0. As it is, those pulling from master will see a ton of breakage immediately, which is going to be painful as gorilla/sessions sees use from a wide range of developers (newbie Gophers to experienced). |
|
Can you share more details here? The cache should only live for one
request; sessions are otherwise not stored in memory across requests.
…On Mon, Dec 18, 2017 at 5:16 AM Romain Menke ***@***.***> wrote:
A way to disable the in memory cache would be great. This package is
unusable in applications that run multiple instances.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#105 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABIcETDijyILlKONBJDuBlr6REcQgK6ks5tBmWTgaJpZM4LwM5f>
.
|
@elithrar My bad, have been looking at too many packages that utilise an in memory cache that is shared across requests. Looking through the source code it was not immediately clear that the Registry was isolated to a single request. Thx for pointing this out! |
Is dep 1.0 still a blocker? According to the status in the readme, dep is safe for production usage: https://github.com/golang/dep#current-status My understanding is that if gorilla/sessions starts using dep, downstream packages shouldn't be affected. See: https://github.com/golang/dep/blob/master/docs/FAQ.md#my-dependers-dont-use-dep-yet-what-should-i-do Any downstream package that's using the master branch should be aware that they've signed up for backwards incompatible changes. The other option would be to create a new repo/package if preserving backwards compatibility is paramount. |
Any downstream package that's using the master branch should be aware
that they've signed up
That hasn’t been the status quo, and the lack of an option in the toolchain
is the pain point for regular users.
dep being in the Go toolchain is strongly preferred before we use it to
break the API here.
We may do it earlier than that, but not without careful consideration.
The other option would be to create a new repo/package if preserving
backwards compatibility is paramount.
That ends up islanding old users & causing a lot of confusion. I’ve not
seen that work well to date.
…On Wed, Jan 10, 2018 at 11:19 PM Dale Hui ***@***.***> wrote:
Is dep 1.0 still a blocker? According to the status in the readme, dep is
safe for production usage: https://github.com/golang/dep#current-status
Namely, the manifest and lock files are stable. See:
https://github.com/golang/dep/wiki/Roadmap#timeline
My understanding is that if gorilla/sessions starts using dep, downstream
packages shouldn't be affected. See:
https://github.com/golang/dep/blob/master/docs/FAQ.md#my-dependers-dont-use-dep-yet-what-should-i-do
Any downstream package that's using the master branch should be aware that
they've signed up for backwards incompatible changes. The other option
would be to create a new repo/package if preserving backwards compatibility
is paramount.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#105 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABIcO-Q_kwTZCommIiIm02ce7dd2afRks5tJbYWgaJpZM4LwM5f>
.
|
What do you think about creating a v2 branch to start all of the v2 work, tagging new releases off of the v2 branch, and requiring v2 users to use |
Yes, that's an option I've considered.
I'd also need to start the work on securecookie *first*, as sessions relies
on securecookie, and I'd like to update that library.
…On Thu, Jan 11, 2018 at 11:45 AM Dale Hui ***@***.***> wrote:
dep ensure -add github.com/gorilla/sessions@^1.0.0 should properly pin
the package.
But yeah, anyone who's used (or using) go get will have a problem and I
guess it's too early to force all of the downstream packages to start using
dep.
What do you think about creating a v2 branch to start all of the v2 work,
tagging new releases off of the v2 branch, and requiring v2 users to use
dep? The v2 branch could be merged back into master when dep is part of
the toolchain.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#105 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABIcFVJM02Np6zhOehopNPu2dmzUwPkks5tJmTEgaJpZM4LwM5f>
.
|
Cool, lemme know where I can help out by tagging me on any issue in |
If you have any opinions on:
* The securecookie v2 punch list:
gorilla/securecookie#43
* What an updated sessions API would look like (read: what problems would
we solve by changing the current API? Do we even need to?)
* Whether the store API needs changes.
There's been a handful of issues tagged as "v2" that provide some
background / user feedback, but I want to make sure we solve either new
problems, or solve old problems *better*, by breaking the API. Breaking for
the sake of breaking makes less sense ;)
…On Thu, Jan 11, 2018 at 4:20 PM Dale Hui ***@***.***> wrote:
Cool, lemme know where I can help out by tagging me on any issue in
sessions or securecookie
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#105 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABIcOppAU5Mj8YyU6US-lRBQ14wgb8oks5tJqVJgaJpZM4LwM5f>
.
|
I think most of the improvements listed in the issue description are good to have.
Regarding "Make sessions.Values better (setters, getters, rather than a map)", I'd like to keep the |
Thanks for the feedback @dhui
Agree. Stores need the session ID (to allow lookup), TTL (to allow expiry) and the session payload itself. There are a few approaches here - I'll omit type Store interface {
Get(id string) (*Session, error)
Save(session *Session) error
Expire(id string) (bool, error)
} Stores would need to care about marshalling
No, but that goes back to the larger, breaking change. We would only support
How would it make it available? In the request context? If so, fetching it from there is the same amount of code—except, with type assertions as context.Value is an Saving, on the other hand, can be done (mostly) automatically, although if a user writes to the response body before the middleware runs, we'll run into issues. The middleware would need to hijack the
I'd need to see an extremely convincing argument for this. I don't see any sensible use-case for why a developer needs to customize the cryptographic primitives of a sessions library. You should not need to replace the CSPRNG, and you shouldn't need to change the AEAD. We'll use HMAC-SHA-512 for auth-only mode & XSalsa20-Poly1305 for encrypted mode (AEAD).
Yes!
Agree! |
You're welcome! Thanks for being open and receptive to different ideas!
Agreed. I think the Store should be responsible for storing the data since there may be more efficient storage mechanisms for the store besides
Yeah, I'm a fan of the middleware setting the
I'm not familiar w/ the
Good point regarding the middleware. We could have 2 middlewares:
Haha, I don't think I have one but I'll try... My best argument is that there's no one size fits all for security. Security is about making trade-offs between usability, performance, and protection against expected attack vectors. The best person to make that decision is the the app developer. Providing a clean crypto interface (sane defaults and allowing customization with ample warnings) would allow developers to customize security for their usecase. e.g. They could use HSMs and/or TRNGs if they wanted to although it's probably overkill for sessions... One other thing regarding the crypto interface: make sure there's a way to change/upgrade the algorithm, key size, and work factor. These things are always change, so a system that can auto upgrade the algo, key size, and work factor will save a lot of future headaches. |
This issue has been automatically marked as stale because it hasn't seen a recent update. It'll be automatically closed in a few days. |
This issue has been automatically marked as stale because it hasn't seen a recent update. It'll be automatically closed in a few days. |
Should this be reopened? |
**Why**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Reference: gorilla/sessions#105 The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger.
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [] Verify that the value in the `Expires/Max-Age` column is `Session` - [] Verify that the HttpOnly column is checked - [] Verify that the Path is `/` - [] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [] Verify you can create a New milmove User - [] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. The name of the Redis key that holds the session data is based on the format `scs:session:token`, where `token` is the session cookie value. In order to revoke an individual session, we need to know the token corresponding to the user's session. To facilitate that lookup, I added a new `session-id` to the RequestLogger. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-cli`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that there is a `session-id` entry in the `middleware/request_logger.go` output that is the same value as the current browser cookie, not the previous one before the user signed in 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Note that this PR does not provide the ability to limit concurrent sessions or revoke individual sessions via the admin interface. That work is being done in a separate branch. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-dev`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **Logging into multiple apps at the same time** 1. Log in to http://milmovelocal:3000/ 2. In a separate tab, log in to http://officelocal:3000 3. In a separate tab, log in to http://adminlocal:3000 4. Refresh each tab. Verify that you are still signed into each app. **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Note that this PR does not provide the ability to limit concurrent sessions or revoke individual sessions via the admin interface. That work is being done in a separate branch. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-dev`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **Logging into multiple apps at the same time** 1. Log in to http://milmovelocal:3000/ 2. In a separate tab, log in to http://officelocal:3000 3. In a separate tab, log in to http://adminlocal:3000 4. Refresh each tab. Verify that you are still signed into each app. **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Note that this PR does not provide the ability to limit concurrent sessions or revoke individual sessions via the admin interface. That work is being done in a separate branch. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-dev`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **Logging into multiple apps at the same time** 1. Log in to http://milmovelocal:3000/ 2. In a separate tab, log in to http://officelocal:3000 3. In a separate tab, log in to http://adminlocal:3000 4. Refresh each tab. Verify that you are still signed into each app. **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Note that this PR does not provide the ability to limit concurrent sessions or revoke individual sessions via the admin interface. That work is being done in a separate branch. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-dev`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **Logging into multiple apps at the same time** 1. Log in to http://milmovelocal:3000/ 2. In a separate tab, log in to http://officelocal:3000 3. In a separate tab, log in to http://adminlocal:3000 4. Refresh each tab. Verify that you are still signed into each app. **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
**Description**: In order to obtain an ATO (Authority to Operate) for MilMove, we need to provide a way to revoke individual user sessions. Currently, session management is provided by JWTs per ADR 15, but JWTs aren't designed to be revoked on an individual basis. Instead, we need to store session data on the server. In this PR, we have chosen Redis because it automatically deletes expired sessions. With Postgres, we would need to run a routine periodically to clean up stale sessions. After researching various session management solutions, I chose `scs` because it was the easiest to integrate, and it supports various stores out of the box. It is the second most popular repo after `gorilla/sessions`. I didn't pick `gorilla/sessions` because it suffers from memory leak issues, and uses its own `context` instead of the `request.Context()` provided by Golang. The maintainers are aware of the issues and have opened a GitHub issue to propose improvements for v2. However, it doesn't look like any progress has been made over the past 2 years, while `scs` has implemented most of those improvements. Note that this PR does not provide the ability to limit concurrent sessions or revoke individual sessions via the admin interface. That work is being done in a separate branch. **Setup**: `docker pull redis` **Reviewer Notes**: Things to test: **milmovelocal auth** 1. Go to milmovelocal:3000 - [ ] Verify that a session cookie named "mil_session_token" is present (Developer Tools -> Application tab -> Cookies (under Storage in the left sidebar)) - [ ] Verify that the value in the `Expires/Max-Age` column is `Session` - [ ] Verify that the HttpOnly column is checked - [ ] Verify that the Path is `/` - [ ] Verify that `SameSite` is `Lax` 2. In your Terminal, run `redis-dev`, then type `KEYS *` - [ ] Verify there is an entry labeled `scs:session:token`, where `token` is the `Value` of the `mil_session_token` cookie 3. Sign in - [ ] Verify that after successful sign in, the `Value` of the `mil_session_token` cookie changes 4. Run `KEYS *` again in the Redis console - [ ] Verify that the previous entry is gone and that a new one corresponding to the new session cookie is present 5. Sign out - [ ] Verify that the previous entry in Redis is gone and that a new one corresponding to the new session cookie is present - [ ] Verify that the session cookie changed in the browser 6. In `serve.go`, on line 504, change the IdleTimeout from 15 minutes to 1 minute 7. Sign in, then wait a little over a minute 8. Try to make a new request without refreshing the browser, for example, filling out the moves form and clicking the Next button - [ ] Verify that you are not able to make a request and that you see an Unauthorized Error. Ideally, the user would be redirected to the sign in page. I'm working on implementing that. **devlocal auth** - [ ] Verify you can sign in and out via devlocal auth flow: http://milmovelocal:3000/devlocal-auth/login - [ ] Verify you can create a New milmove User - [ ] Verify you can create a New dps User **Role based auth** 1. In your `.envrc.local`, add `export FEATURE_FLAG_ROLE_BASED_AUTH=true` 2. Stop the server, run `direnv allow` 3. run `echo $FEATURE_FLAG_ROLE_BASED_AUTH` to make sure it's `true` 4. run `make server_run` 5. Go to milmovelocal:3000 and make sure you can sign in and out **Logging into multiple apps at the same time** 1. Log in to http://milmovelocal:3000/ 2. In a separate tab, log in to http://officelocal:3000 3. In a separate tab, log in to http://adminlocal:3000 4. Refresh each tab. Verify that you are still signed into each app. **References**: [gorilla sessions issues](gorilla/sessions#105) [scs repo](https://github.com/alexedwards/scs)
With Go 1.7's
request.Context()
requiring a (non-trivial!) breaking API change, I figured it would be a good time to discuss what a "v2" of this package would look like. Further, with golang/dep on the horizon, vendoring/pinning dependencies is more common-place, allowing us to 'safely' leave v1 API users as-is whilst improving the library for others.What I see as key changes:
Save(w, r)
rather than(r, w)
Save
(forgetting to save sucks, and is common enough!)There is no schedule for this yet. Open to feedback.
The text was updated successfully, but these errors were encountered: