Skip to content

Commit

Permalink
Merge pull request #480 from mozilla-iam/move_duosecurity
Browse files Browse the repository at this point in the history
Migrate duoSecurity into accessRules
  • Loading branch information
dividehex authored Oct 31, 2024
2 parents 349eb3d + 03003e8 commit b92c965
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 297 deletions.
66 changes: 15 additions & 51 deletions terraform/actions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ locals {
id = auth0_action.continueEndPoint.id
display_name = auth0_action.continueEndPoint.name
}
duoSecurity = {
id = auth0_action.duoSecurity.id
display_name = auth0_action.duoSecurity.name
}
samlMappings = {
id = auth0_action.samlMappings.id
display_name = auth0_action.samlMappings.name
Expand Down Expand Up @@ -80,53 +76,6 @@ resource "auth0_action" "continueEndPoint" {
}
}

resource "auth0_action" "duoSecurity" {
name = format("duoSecurity")
runtime = "node18"
deploy = true
code = file("${path.module}/actions/duoSecurity.js")

supported_triggers {
id = "post-login"
version = "v3"
}

dependencies {
name = "aws-sdk"
version = "2.1646.0"
}

dependencies {
name = "jsonwebtoken"
version = "9.0.2"
}

secrets {
name = "duo_apihost_mozilla"
value = local.parsed_secrets["duoSecurity_duo_apihost"]
}

secrets {
name = "duo_ikey_mozilla"
value = local.parsed_secrets["duoSecurity_duo_ikey"]
}

secrets {
name = "duo_skey_mozilla"
value = local.parsed_secrets["duoSecurity_duo_skey"]
}

secrets {
name = "accessKeyId"
value = local.parsed_secrets["duoSecurity_accessKeyId"]
}

secrets {
name = "secretAccessKey"
value = local.parsed_secrets["duoSecurity_secretAccessKey"]
}
}

resource "auth0_action" "samlMappings" {
name = format("samlMappings")
runtime = "node18"
Expand Down Expand Up @@ -244,6 +193,21 @@ resource "auth0_action" "accessRules" {
version = "2.1646.0"
}

secrets {
name = "duo_apihost_mozilla"
value = local.parsed_secrets["duoSecurity_duo_apihost"]
}

secrets {
name = "duo_ikey_mozilla"
value = local.parsed_secrets["duoSecurity_duo_ikey"]
}

secrets {
name = "duo_skey_mozilla"
value = local.parsed_secrets["duoSecurity_duo_skey"]
}

secrets {
name = "accessKeyId"
value = local.parsed_secrets["accessRules_accessKeyId"]
Expand Down
46 changes: 30 additions & 16 deletions terraform/actions/accessRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ exports.onExecutePostLogin = async (event, api) => {
console.log("Running actions:", "accessRules");

// Retrieve and return a secret from AWS Secrets Manager
const getSecrets = async (AWS, accessKeyId, secretAccessKey) => {
const getSecrets = async () => {
try {

if (!accessKeyId || !secretAccessKey) {
if (!event.secrets.accessKeyId || !event.secrets.secretAccessKey) {
throw new Error('AWS access keys are not defined.');
}

// set AWS config so we can retrieve secrets
// Set up AWS client
AWS.config.update({
region: 'us-west-2',
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey
accessKeyId: event.secrets.accessKeyId,
secretAccessKey: event.secrets.secretAccessKey
});

const secretsManager = new AWS.SecretsManager();
Expand All @@ -40,9 +39,7 @@ exports.onExecutePostLogin = async (event, api) => {
}

// Load secrets
const accessKeyId = event.secrets.accessKeyId;
const secretAccessKey = event.secrets.secretAccessKey;
const secrets = await getSecrets(AWS, accessKeyId, secretAccessKey);
const secrets = await getSecrets();
const jwtMsgsRsaSkey = secrets.jwtMsgsRsaSkey;

// postError(code)
Expand Down Expand Up @@ -84,6 +81,12 @@ exports.onExecutePostLogin = async (event, api) => {
}
}

if (!event.user.email_verified) {
console.log(`User primary email NOT verified, refusing login for ${event.user.email}`);
// This post error is broken in sso dashboard
postError("primarynotverified", event, api, jwt, jwtMsgsRsaSkey);
return;
}

const namespace = 'https://sso.mozilla.com/claim';

Expand All @@ -93,6 +96,13 @@ exports.onExecutePostLogin = async (event, api) => {
'[email protected]', // MOC see: https://bugzilla.mozilla.org/show_bug.cgi?id=1423903
];

const duoConfig = {
"host": event.secrets.duo_apihost_mozilla,
"ikey": event.secrets.duo_ikey_mozilla,
"skey": event.secrets.duo_skey_mozilla,
"username": event.user.email,
};

// Check if array A has any occurrence from array B
const hasCommonElements = (A, B) => {
return A.some(element => B.includes(element));
Expand Down Expand Up @@ -235,6 +245,17 @@ exports.onExecutePostLogin = async (event, api) => {
let aai = [];
let aal = "UNKNOWN";

// Allow certain LDAP service accounts to fake their MFA. For all other LDAPi accounts, enforce MFA
if (event.connection.strategy === "ad") {
if (mfaBypassAccounts.includes(event.user.email)) {
console.log(`LDAP service account (${event.user.email}) is allowed to bypass MFA`);
aai.push("2FA");
} else {
api.multifactor.enable("duo", { "providerOptions": duoConfig, "allowRememberBrowser": true });
console.log(`duosecurity: ${event.user.email} is in LDAP and requires 2FA check`);
}
}

const profileData = getProfileData(event.connection.name);

//GitHub attribute
Expand Down Expand Up @@ -266,12 +287,6 @@ exports.onExecutePostLogin = async (event, api) => {
aai.push("HIGH_ASSURANCE_IDP");
}

// Allow certain LDAP service accounts to fake their MFA
if (mfaBypassAccounts.includes(event.user.email) && (event.connection.strategy === "ad")) {
console.log(`LDAP service account (${event.user.email}) is allowed to bypass MFA`);
aai.push("2FA");
}

// AAI (AUTHENTICATOR ASSURANCE INDICATOR) REQUIREMENTS
//
// Note that user.aai is set in another rule (rules/aai.js)
Expand Down Expand Up @@ -369,7 +384,6 @@ exports.onExecutePostLogin = async (event, api) => {
postError(decision);
return;
}

} catch (err) {
// All error should be caught here and we return the callback handler with the error
console.log("AccessRules:", err);
Expand Down
117 changes: 0 additions & 117 deletions terraform/actions/duoSecurity.js

This file was deleted.

Loading

0 comments on commit b92c965

Please sign in to comment.