Created
March 17, 2022 11:16
-
-
Save joho/243f7f0ed157ca88c03525e6e7b4f099 to your computer and use it in GitHub Desktop.
Auth0 post-login action to check login against Kolide API to ensure login is from a managed and healthy device
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Handler that will be called during the execution of a PostLogin flow. | |
* | |
* @param {Event} event - Details about the user and the context in which they are logging in. | |
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. | |
*/ | |
const sdk = require('api')('@kolidek2/v0.1.0#fs30l4gl0u0cv0n'); | |
const { DateTime } = require('luxon'); | |
const maxMinuteSinceLastSeen = 5 | |
const maxFailedChecks = 7 | |
exports.onExecutePostLogin = async (event, api) => { | |
const apiKey = event.secrets.KOLIDE_API_KEY; | |
try { | |
sdk.auth(apiKey) | |
const search = encodeURIComponent(event.user.email) | |
const personResp = await sdk.get('/people', {search}) | |
if (personResp.data && personResp.data.length !== 1) { | |
throw new Error('No exact match on email') | |
} | |
const person = personResp.data[0] | |
const devicesResp = await sdk.get(`/people/${person.id}/devices`) | |
const loginIP = event.request.ip | |
const recentDevices = devicesResp.data. | |
filter((device) => device.remote_ip === loginIP). | |
sort((a, b) => b.last_seen_at.localeCompare(a.last_seen_at)) | |
if (recentDevices && recentDevices.length === 0) { | |
api.access.deny('Login not from recognised device') | |
return | |
} | |
const currentDevice = recentDevices[0] | |
const deviceLastSeen = DateTime.fromISO(currentDevice.last_seen_at) | |
const sinceLastSeen = deviceLastSeen.diffNow(['minutes']) | |
if (sinceLastSeen.minutes > maxMinuteSinceLastSeen) { | |
api.access.deny('Device has not checked in with Kolide recently enough') | |
return | |
} | |
if (currentDevice.failures > maxFailedChecks) { | |
api.access.deny('Device failing too many Kolide checks') | |
return | |
} | |
} catch (e) { | |
let message | |
if (e && e.message) { | |
message = e.message | |
} else if (e && e.status && e.statusText && e.url) { | |
message = `${e.url} - ${e.status} ${e.statusText}` | |
} | |
console.error(event.user.email, event.request.ip, message) | |
api.access.deny('Error talking to Kolide') | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment