Skip to content

Instantly share code, notes, and snippets.

@joho
Created March 17, 2022 11:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joho/243f7f0ed157ca88c03525e6e7b4f099 to your computer and use it in GitHub Desktop.
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
/**
* 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