feat: added initial server sso key rotation semantics (#2696)

This commit is contained in:
Wyatt Johnson
2019-11-07 16:53:28 -05:00
committed by Kim Gardner
parent 59b8dfccda
commit 2dbba52fbd
14 changed files with 441 additions and 88 deletions
+13 -2
View File
@@ -7,6 +7,8 @@ import {
} from "coral-server/graph/tenant/schema/__generated__/types";
import { translate } from "coral-server/services/i18n";
import { SSOKey } from "../settings";
export const getDefaultReactionConfiguration = (
bundle: FluentBundle
): GQLReactionConfiguration => ({
@@ -28,10 +30,19 @@ export const getDefaultStaffConfiguration = (
label: translate(bundle, "Staff", "staff-label"),
});
export function generateSSOKey() {
export function generateRandomString(size: number, drift = 5) {
return crypto
.randomBytes(size + Math.floor(Math.random() * drift))
.toString("hex");
}
export function generateSSOKey(createdAt: Date): SSOKey {
// Generate a new key. We generate a key of minimum length 32 up to 37 bytes,
// as 16 was the minimum length recommended.
//
// Reference: https://security.stackexchange.com/a/96176
return crypto.randomBytes(32 + Math.floor(Math.random() * 5)).toString("hex");
const secret = generateRandomString(32, 5);
const kid = generateRandomString(8, 3);
return { kid, secret, createdAt };
}
+34 -16
View File
@@ -125,8 +125,8 @@ export async function createTenant(
admin: true,
stream: true,
},
key: generateSSOKey(),
keyGeneratedAt: now,
// TODO: [CORL-754] (wyattjoh) remove this in favor of generating this when needed
keys: [generateSSOKey(now)],
},
oidc: {
enabled: false,
@@ -277,25 +277,17 @@ export async function updateTenant(
* for the specified Tenant. All existing user sessions signed with the old
* secret will be invalidated.
*/
export async function regenerateTenantSSOKey(mongo: Db, id: string) {
// Construct the update.
const update: DeepPartial<Tenant> = {
auth: {
integrations: {
sso: {
key: generateSSOKey(),
keyGeneratedAt: new Date(),
},
},
},
};
export async function createTenantSSOKey(mongo: Db, id: string, now: Date) {
// Construct the new key.
const key = generateSSOKey(now);
// Update the Tenant with this new key.
const result = await collection(mongo).findOneAndUpdate(
{ id },
// Serialize the deep update into the Tenant.
{
$set: dotize(update),
$push: {
"auth.integrations.sso.keys": key,
},
},
// False to return the updated document instead of the original
// document.
@@ -304,3 +296,29 @@ export async function regenerateTenantSSOKey(mongo: Db, id: string) {
return result.value || null;
}
export async function deprecateTenantSSOKey(
mongo: Db,
id: string,
kid: string,
deprecateAt: Date
) {
// Update the tenant.
const result = await collection(mongo).findOneAndUpdate(
{ id },
{
$set: {
"auth.integrations.sso.keys.$[keys].deprecateAt": deprecateAt,
},
},
{
// False to return the updated document instead of the original
// document.
returnOriginal: false,
// Add an ArrayFilter to only update one of the keys.
arrayFilters: [{ "keys.kid": kid }],
}
);
return result.value || null;
}