Open j3k0 opened 7 years ago
Right now we have a secret
that one can use to do w/ever on any server. This is problematic, because:
What if we use JWT? Though it would still require secret
for verifying signatures, we wouldn't have to include it in every request. Then instead of multiple tokens, we simply specify something like:
// config.js
eventsToken: jwtEncode({
user: pkg.api,
for: 'events',
allows: ['read']
}, process.env.API_SECRET) // "xxx.babsafasf.signature"
// middleware
app.use(middleware.requireJwtFor('events', ['read']}))
This has somewhat similar drawbacks because it allows to create any token with any access level, if secret
is ever leaked, but only read
access token is transmitted over the wire, and secret
lives (hopefuly) securely in process memory. We can come up with more sophisticated issuing scheme later where secret is only know to, say, DIRECTORY
, and we just put jwtEncode
result in particular service's config.
Older services can have something like jwtEncode({skeletonKey: true})
inside their in/out API_SECRET
. Though, with .
being in JWT, we'll have to change fake auth.
I'll study the suggestions (I don't know anything about JWT). This is low-priority, something to consider to improve overall security after we're done with the rest.
Ok, after minimal study, I like the JWT suggestion.
For a smooth transition, I suppose we can do it this way:
apiSecret == process.env.API_SECRET
, authentication middleware just accepts it.Adding more advanced permissions can be a second step. I'm thinking maybe list in the JWT the list of allowed endpoint ("allows": ["GET /events", "POST /events"]
).. Anyway: this would be a second step.
The above would be for server-side. Client-side (in places where we used the global API_SECRET for making outgoing requests), I'm thinking to add an optional SERVICE_PORT_8000_API_SECRET
env var, which defaults to the global API_SECRET
.
Thoughts?
In order to limit the distribution of the production
API_SECRET
, I'd like to be able to define multiple inboundAPI_SECRET
for each service, starting withganomede-directory
(for which it might be useful right away).Suggested solution:
API_SECRET
is not a comma separated list of valid secret keys.Advantage: It's backward compatible.
Inconvenient: For outbound requests using
API_SECRET
, we need to decide which API_SECRET is the one to use. I think it's logical to use the first in the array (apiSecret[0]
)... Anyway, it's not relevant to ganomede-directory (no outbound request).Hopefully it's gonna be easy to integrate in other modules as well (when it's needed).
Additional thought (for other services), allow to specify per-service secrets. Like
EVENTS_API_SECRET
,COORDINATOR_API_SECRET
, ... with a fallback to the globalAPI_SECRET[0]
.