Merged PR 619888: Guardian - Add updates for compliance build

- Add new functions to automatically generate CredScan calls on a given repository root.
- Allow automatic generation of baselines/suppressions.
- Add user specified environment variables, and pick up variables passed in by cloudbuild.
- Add option to use Cloudbuild guardian package cache.

Related work items: #1840363
This commit is contained in:
Pasindu Gunasekara 2021-06-28 23:03:35 +00:00
Родитель 7b4dfdf2bb
Коммит d24a53e0f6
16 изменённых файлов: 404 добавлений и 28 удалений

Просмотреть файл

@ -1,4 +1,12 @@
# Generating Baselines and Suppression files for BuildXL builds
## Automatic/Cloudbuild generation
To automatically generate baselines or suppressions pass `/p:[Tool.Guardian]genBaseline=1` for baselines or `/p:[Tool.Guardian]genSuppressions=1` for suppressions (but not both at once) as a command line argument to BuildXL.
Set `autoGeneratedBaselineSuppressionLocation` in the SDK arguments to the directory where the generated baselines/suppressions should be written. Then, depending on which of the above flags were passed in, set `baselineFileName` or `suppressionFileName` for the name of each baseline/suppression file to be generated for the given call to the Guardian SDK.
Once the build completes, check the directory specified in `autoGeneratedBaselineSuppressionLocation` for the newly generated baselines/suppressions.
## Manual local only generation
The `guardian baseline` and `guardian suppress` commands can be used to baseline and suppress guardian violations. These must be run manually and committed to the repository.
1. Run BuildXL to get a failing build with Guardian violations.

Просмотреть файл

@ -0,0 +1,21 @@
# Compliance Build on Cloudbuild
The compliance build on Cloudbuild will run various Guardian tools against the repository root on CB builds to ensure that the repository complies with various Microsoft security standards. Currently it is opt in while repositories are onboarded, but it will eventually be made mandatory for all builds. In its current state, the compliance build will run CredScan against the repo root as soon as it is checked out on Cloudbuild.
## Enabling Compliance Build
To enable (or disable) compliance build, use the `EnableGuardianBuild` flag in your Cloudbuild configuration when submitting a new build. Additionally, the `GuardianBuildFlags` argument (optional) can be added to pass flags into the Guardian SDK.
```
{
'SpecificRunnerOptions' : {
'EnableGuardianBuild' : true,
'GuardianBuildFlags' : '/p:[Tool.Guardian]genBaseline=1',
},
}
```
## Generating Baselines/Suppressions on Cloudbuild
Suppressions and baselines can be automatically generated on Cloudbuild by setting `/p:[Tool.Guardian]genBaseline=1` for baselines or `/p:[Tool.Guardian]genSuppressions=1` for suppressions (but not both at once) inside the `GuardianBuildFlags` argument in the configuration for the build. This will cause the Compliance build to pass by not allowing the build to break on Guardian errors, and will generate a set of baselines/suppressions under the `{ComplianceBuildLogDirectory}/Guardian` directory. These can be retrieved using the Cloudbuild web interface or with the log drop for the build.
Once generated, manually copy these files to the `{RepositoryRoot}/.config/buildxl/compliance` directory, and check them into the repository. Finally, rebuild without the genBaseline or genSuppressions flags and ensure that the Compliance build passes with the newly generated baselines or suppressions.
Note: The flags above should *only* be used temporarily to generate baselines for a single build. They should not be set in the queue configuration for a repository.

Просмотреть файл

@ -0,0 +1,10 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import * as Deployment from "Sdk.Deployment";
@@public
export const deployment : Deployment.Definition = {
contents: [
f`jsonSdk.dsc`,
f`module.config.dsc`
]
};

Просмотреть файл

@ -0,0 +1,4 @@
module({
name: "Sdk.Guardian",
projects: [ p`Tool.Guardian.dsc`, p`Tool.Guardian.CredScan.dsc` ]
});

Просмотреть файл

@ -1,4 +0,0 @@
module({
name: "Sdk.Guardian",
projects: [ p`Tool.Guardian.dsc` ]
});

Просмотреть файл

@ -0,0 +1,112 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import {Transformer} from "Sdk.Transformers";
const autoGenerateBaselines = Environment.getFlag(guardianGenerateBaselines);
const autoGenerateSuppressions = !autoGenerateBaselines && Environment.getFlag(guardianGenerateSuppressions);
const complianceBaselineSuppressionLocation = Environment.hasVariable("BUILDXL_ENLISTMENT_ROOT") ? d`${Environment.getPathValue("BUILDXL_ENLISTMENT_ROOT")}/.config/buildxl/compliance` : undefined;
const guardianConfigFile = f`${Context.getMount("SourceRoot").path}/guardianBuildConfig.gdnconfig`;
// Compliance build specific Environment variables
const directoriesNamesToIgnore = "[Tool.Guardian]complianceIgnoreDirectories";
const filesPerCredScanCall = "[Tool.Guardian]complianceFilesPerCredScanCall";
/**
* Calling this function will create Guardian pips with CredScan only on the entire repository from the guardianBuildRoot directory.
*
* When running on Cloudbuild, it is not necessary to provide a Guardian install location. Instead the Guardian binaries will
* be from acquired from the Guardian drop.
*/
@@public
export function runCredScanOnEntireRepository(guardianToolRoot : StaticDirectory, guardianBuildRoot : Directory) : Transformer.ExecuteResult[] {
if (!Environment.hasVariable("TOOLPATH_GUARDIAN")) {
Contract.fail("Guardian drop root must be provided with the 'TOOLPATH_GUARDIAN' environment variable.");
}
return addGuardianPerDirectoryForRepository(guardianBuildRoot, guardianToolRoot, d`${Environment.getPathValue("TOOLPATH_GUARDIAN")}`);
}
/**
* Goes through each directory under the given root directory and creates CredScan calls per ~500 files.
*/
function addGuardianPerDirectoryForRepository(rootDirectory : Directory, guardianToolRoot : StaticDirectory, guardianDrop : Directory) : Transformer.ExecuteResult[] {
let results : Transformer.ExecuteResult[] = [];
let files : File[] = glob(rootDirectory, "*");
let directories = globFolders(rootDirectory, "*", /*recursive*/false);
let directoryIndex = 0;
// These are directories that are local to a given repository that are not checked in remotely
const directoryAtomsToIgnore = Set.create<PathAtom>(
// Defaults
a`.git`,
a`.cloudbuild`,
a`.corext`,
a`Out`,
a`node_modules`,
// User specified
...addIfLazy(Environment.hasVariable(directoriesNamesToIgnore), () => {
const directoryList = Environment.getStringValue(directoriesNamesToIgnore).split(",");
return directoryList.map(dir => a`${dir}`);
})
);
const directoryPathsToIgnore = Set.create<Directory>(
d`${Environment.getPathValue("BUILDXL_ENLISTMENT_ROOT")}/common/temp` // well known path for rush install (not part of initially checked out sources)
);
const minFilesPerCall = Environment.hasVariable(filesPerCredScanCall) ? Environment.getNumberValue(filesPerCredScanCall) : 500;
while (directoryIndex < directories.length) {
if (directoryAtomsToIgnore.contains(directories[directoryIndex].name) || directoryPathsToIgnore.contains(directories[directoryIndex])) {
directoryIndex++;
continue;
}
files = files.concat(glob(directories[directoryIndex], "*"));
directories = directories.concat(globFolders(directories[directoryIndex], "*", /*recursive*/false));
if (files.length >= minFilesPerCall || (directoryIndex === directories.length - 1 && files.length > 0)) {
results.push(createGuardianCall(guardianToolRoot, guardianDrop, files, directoryIndex));
files = [];
}
directoryIndex++;
}
return results;
}
/**
* Generates a Guardian call for the CredScan compliance build.
* Baselines/Suppressions will be picked up from {SourceRoot}/.config/buildxl/compliance automatically.
* LogLevel is set to Warning in Guardian.
*/
function createGuardianCall(guardianToolRoot : StaticDirectory, guardianDrop : Directory, files : File[], directoryIndex : number) : Transformer.ExecuteResult {
const exportDir = Context.getNewOutputDirectory("credScan");
const baselines = glob(complianceBaselineSuppressionLocation, "*.gdnbaselines");
const suppressions = glob(complianceBaselineSuppressionLocation, "*.gdnsuppress");
// Generate a TSV file for all files to be scanned
const tsvFile = Transformer.writeAllLines(p`${exportDir.path}/guardian.TSV`, files.map(file => file.path));
const guardianArgs : GuardianArguments = {
guardianToolRootDirectory: guardianToolRoot,
guardianConfigFile: guardianConfigFile, // Pick up default config from drop directory
guardianResultFile: f`${exportDir.path}/credScanResult.sarif`,
guardianPackageDirectory: d`${guardianDrop}/packages`,
guardianToolWorkingDirectory: exportDir, // Set this to pick up the newly generated tsv file automatically
filesToBeScanned: files,
additionalDependencies: [tsvFile],
logLevel: "Warning", // Display only warnings and errors only to simplify debugging and reduce log file size
baselineFiles: baselines.length > 0 ? baselines : undefined,
suppressionFiles: suppressions.length > 0 ? suppressions : undefined,
autoGeneratedBaselineSuppressionLocation: autoGenerateBaselines || autoGenerateSuppressions
? d`${Context.getMount("LogsDirectory").path}/Guardian`
: undefined,
baselineFileName: autoGenerateBaselines ? a`${directoryIndex.toString()}.gdnbaselines` : undefined,
suppressionFileName: autoGenerateSuppressions ? a`${directoryIndex.toString()}.gdnsuppressions` : undefined,
};
return runGuardian(guardianArgs, /*skipInstall*/true);
}

Просмотреть файл

@ -7,15 +7,26 @@ import * as Json from "Sdk.Json";
@@public
export const guardianTag = "msguardian";
const guardianDisableFlag = "[Tool.Guardian]disable";
const guardianWarnOnlyFlag = "[Tool.Guardian]warnOnly";
/** Environment Variables */
export const guardianDisableFlag = "[Tool.Guardian]disable";
export const guardianWarnOnlyFlag = "[Tool.Guardian]warnOnly";
export const guardianBaselineSuppressionDirectory = "[Tool.Guardian]baselineSuppressDir";
export const guardianGenerateBaselines = "[Tool.Guardian]genBaseline";
export const guardianGenerateSuppressions = "[Tool.Guardian]genSuppressions";
const guardianInstallMutex = "BuildXL.Tools.Guardian.Install.Phase";
const guardianExecutableName : PathAtom = PathAtom.create("guardian.cmd");
const defaultGuardianToolWorkingDirectory = d`${Context.getMount("SourceRoot").path}`;
const cloudbuildToolPath : Directory = Environment.hasVariable("TOOLPATH_GUARDIAN") ? d`${Environment.getDirectoryValue("TOOLPATH_GUARDIAN")}` : undefined;
const cloudBuildDotNetDirectory = cloudbuildToolPath ? d`${cloudbuildToolPath}/dotnetX64` : undefined;
const cloudBuildTempDirectory = cloudbuildToolPath ? d`${cloudbuildToolPath.parent.parent.path}/temp` : undefined;
const guardianUntrackedDirectories = addIfLazy(Context.getCurrentHost().os === "win", () => [
// Accessed by the Guardian CLI
d`${Context.getMount("ProgramFilesX86").path}/dotnet`,
d`${Context.getMount("ProgramFiles").path}/dotnet`,
...addIf(cloudBuildDotNetDirectory !== undefined, cloudBuildDotNetDirectory),
d`${Context.getMount("ProgramData").path}/Microsoft/NetFramework`,
d`${Context.getMount("ProgramData").path}/Microsoft/VisualStudio/Setup`,
// Config files accessed by nuget during Guardian install phase
@ -28,20 +39,31 @@ const guardianUntrackedDirectories = addIfLazy(Context.getCurrentHost().os === "
// Nuget will cache packages under ~/.nuget/packages, however they will always get copied over to the package install directory
// Since we track the package install directory, we will untrack the ~/.nuget/packages directory.
d`${Context.getMount("UserProfile").path}/.nuget/packages`,
// Guardian occasionally does not honour the TMP/TEMP variables, and instead will write temp files to other locations listed below
// The temp directory on cloudbuild will always be created under X:\a\b\temp, when the cloudbuild drop is at X:\a\b\c\d (this location is not expected to change between builds)
// TODO: Remove this line once the Guardian team fixes this bug to use the temp directory specified in TEMP/TMP instead.
...addIf(cloudBuildTempDirectory !== undefined, cloudBuildTempDirectory),
]);
/**
* Tool definition for guardian
* Note: Package root is untracked because we rely on the .gdn/c directory to know when a new Guardian tool is available.
*/
function getGuardianTool(guardianRoot : StaticDirectory, guardianPaths : GuardianPaths) : Transformer.ToolDefinition {
function getGuardianTool(args: GuardianArguments, guardianPaths : GuardianPaths) : Transformer.ToolDefinition {
return {
exe: findGuardianExecutable(guardianRoot),
exe: findGuardianExecutable(args.guardianToolRootDirectory),
description: "Microsoft Guardian",
dependsOnWindowsDirectories: true,
dependsOnAppDataDirectory: true,
prepareTempDirectory: true,
untrackedDirectoryScopes: [...guardianUntrackedDirectories, d`${guardianPaths.install}`],
untrackedDirectoryScopes: [
...guardianUntrackedDirectories,
d`${guardianPaths.install}`,
// When using the integrated Guardian package (such as the one on CloudBuild), Guardian may write under these paths even though it has a temporary directory prepared.
d`${args.guardianToolRootDirectory.path}/temp`,
d`${args.guardianToolRootDirectory.path}/tmp`,
...addIf(args.autoGeneratedBaselineSuppressionLocation !== undefined, args.autoGeneratedBaselineSuppressionLocation),
],
// Untracking localRepo/.gdnhistory to ignore double writes between guardian init and guardian run
// the history in here is not important because each Guardian call gets it's own .gdnhistory file.
// globalRepo/.gdnhistory will also be read from, but it will not be written to.
@ -64,7 +86,7 @@ function findGuardianExecutable(guardianRoot : StaticDirectory) : File {
}
/**
* Schedules a guardian pip with the specified arguments.
* Schedules a guardian pip with the specified arguments. The install step can be skipped when a package cache is available using the skipInstall option.
*
* Guardian is currently only supported on Windows.
*
@ -82,7 +104,7 @@ function findGuardianExecutable(guardianRoot : StaticDirectory) : File {
* d. guardian break: Look at processed data from previous step, return bad exit code if breaking results found and export results to file.
*/
@@public
export function runGuardian(args: GuardianArguments) : Transformer.ExecuteResult {
export function runGuardian(args: GuardianArguments, skipInstall?: boolean) : Transformer.ExecuteResult {
validateArguments(args);
let guardianResult = undefined;
@ -93,8 +115,13 @@ export function runGuardian(args: GuardianArguments) : Transformer.ExecuteResult
else {
const outputDirectory = Context.getNewOutputDirectory("guardianOut");
const guardianPaths = createGuardianPaths(outputDirectory, args.guardianPackageDirectory);
const guardianTool = getGuardianTool(args.guardianToolRootDirectory, guardianPaths);
let guardianDependencies : Transformer.InputArtifact[] = [args.guardianToolRootDirectory, f`${guardianPaths.globalGuardianRepo}`, args.guardianConfigFile];
const guardianTool = getGuardianTool(args, guardianPaths);
let guardianDependencies : Transformer.InputArtifact[] = [
args.guardianToolRootDirectory,
f`${guardianPaths.globalGuardianRepo}`,
args.guardianConfigFile,
...addIfLazy(args.additionalDependencies !== undefined, () => args.additionalDependencies)
];
// 0. Create a Guardian settings
const genericSettingsFile = generateGenericGuardianSettingsFile(guardianPaths);
@ -106,7 +133,7 @@ export function runGuardian(args: GuardianArguments) : Transformer.ExecuteResult
// 1. Initialize Guardian for this Guardian run
// - Settings files from previous step not necessary here, can be run concurrently with the WriteFile operation.
const initializeResult = initializeGuardian(guardianTool, guardianPaths, guardianDependencies);
const initializeResult = initializeGuardian(args, guardianTool, guardianPaths, guardianDependencies);
// Steps below this depend on the results of step 0 and step 1
guardianDependencies = guardianDependencies.concat([
@ -116,11 +143,15 @@ export function runGuardian(args: GuardianArguments) : Transformer.ExecuteResult
policyNames
]);
if (!skipInstall)
{
// 2. Run Guardian Install phase
const installResult = runGuardianInstall(args, guardianTool, installSettingsFile, guardianDependencies, guardianPaths);
guardianDependencies = guardianDependencies.push(installResult.getOutputFile(guardianPaths.installLog.path));
}
// 3. Guardian run to run static analysis tools specified in config file, break build if any breaking changes are found, and export results.
guardianDependencies = guardianDependencies.concat([installResult.getOutputFile(guardianPaths.installLog.path), genericSettingsFile]);
guardianDependencies = guardianDependencies.push(genericSettingsFile);
guardianResult = runGuardianInternal(args, guardianTool, genericSettingsFile, guardianDependencies, guardianPaths);
}
@ -191,7 +222,7 @@ function createGuardianPaths(outputDirectory : Directory, packageDirectory : Dir
globalHistory: p`${Context.getMount("SourceRoot").path}/.gdn/internal.gdnhistory`,
installLog: f`${outputDirectory}/install`,
policyNamesPackageConfig: p`${outputDirectory}/buildxl_policy_names.gdnpackage`,
microsoftDefaultPolicyPackageConfig: p`${outputDirectory}/buildxl_policy_microsoft.gdnpackage`
microsoftDefaultPolicyPackageConfig: p`${outputDirectory}/buildxl_policy_microsoft.gdnpackage`,
};
}
@ -262,17 +293,24 @@ function generateGuardianSettingsFile(outputPath : Path, settings : Object, desc
/**
* Initialize Guardian under a new output directory for this run. This will allow BuildXL to isolate each Guardian call into it's own repository.
*/
function initializeGuardian(guardianTool : Transformer.ToolDefinition, guardianPaths : GuardianPaths, guardianDependencies : Transformer.InputArtifact[] ) : Transformer.ExecuteResult {
function initializeGuardian(args : GuardianArguments, guardianTool : Transformer.ToolDefinition, guardianPaths : GuardianPaths, guardianDependencies : Transformer.InputArtifact[]) : Transformer.ExecuteResult {
const arguments : Argument[] = [
Cmd.argument("init"),
Cmd.argument("--force"),
Cmd.option("--logger-level ", args.logLevel !== undefined ? args.logLevel.toString() : undefined)
];
return Transformer.execute({
tool: guardianTool,
tags: [ guardianTag ],
arguments: [Cmd.argument("init"), Cmd.argument("--force")],
arguments: arguments,
workingDirectory: d`${guardianPaths.localGuardianRepo.parent}`,
dependencies: guardianDependencies,
outputs: [ d`${guardianPaths.localGuardianRepo}` ],
successExitCodes: getSuccessExitCodes(),
warningRegex: getWarningRegex(),
description: "Guardian Initialize"
description: "Guardian Initialize",
environmentVariables: getEnvironmentVariables(args)
});
}
@ -287,6 +325,7 @@ function runGuardianInstall(args : GuardianArguments, guardianTool : Transformer
Cmd.option("--settings-file ", settingsFile.path),
Cmd.option("--config ", args.guardianConfigFile.path),
Cmd.option("--logger-filepath ", guardianPaths.installLog.path),
Cmd.option("--logger-level ", args.logLevel !== undefined ? args.logLevel.toString() : undefined),
/** TODO: Remove this option */
Cmd.option("--package-config ", Cmd.join(" ", [guardianPaths.policyNamesPackageConfig, guardianPaths.microsoftDefaultPolicyPackageConfig]))
];
@ -303,7 +342,8 @@ function runGuardianInstall(args : GuardianArguments, guardianTool : Transformer
acquireMutexes: [ guardianInstallMutex ],
successExitCodes: getSuccessExitCodes(),
warningRegex: getWarningRegex(),
description: "Guardian Install"
description: "Guardian Install",
environmentVariables: getEnvironmentVariables(args)
});
}
@ -326,7 +366,9 @@ function runGuardianInternal(args : GuardianArguments, guardianTool : Transforme
Cmd.option("--suppression-file ", Cmd.join(" ", args.suppressionFiles && args.suppressionFiles.map(e => e.path))),
Cmd.options("--suppression-set ", args.suppressionSets),
Cmd.flag("--no-policy", args.noPolicy),
Cmd.option("--policy ", args.policy)
Cmd.option("--policy ", args.policy),
Cmd.option("--logger-level ", args.logLevel !== undefined ? args.logLevel.toString() : undefined),
...getBaselineOrSuppressOptions(args),
];
// Dependencies
@ -370,7 +412,8 @@ function runGuardianInternal(args : GuardianArguments, guardianTool : Transforme
outputs: outputs,
successExitCodes: getSuccessExitCodes(),
warningRegex: getWarningRegex(),
description: "Guardian Run"
description: "Guardian Run",
environmentVariables: getEnvironmentVariables(args)
});
return result;
@ -390,6 +433,53 @@ function getWarningRegex() : string {
return Environment.getFlag(guardianWarnOnlyFlag) ? "\\[Error\\].*" : undefined;
}
/**
* Merges cloudbuild and user specified environment variables.
*/
function getEnvironmentVariables(args : GuardianArguments) : Transformer.EnvironmentVariable[] {
const cbEnvVars = getCloudbuildEnvironmentVariables();
return args.environmentVariables === undefined
? cbEnvVars
: args.environmentVariables.concat(cbEnvVars); // Cloudbuild variables should override user provided variables here
}
/**
* If the TOOLPATH_GUARDIAN environment variable is set, then Guardian should be running on Cloudbuild.
* Add dotnet to the PATH variable for Guardian calls on Cloudbuild.
*/
function getCloudbuildEnvironmentVariables() : Transformer.EnvironmentVariable[] {
if (cloudbuildToolPath) {
return [
{ name: "PATH", separator: ";", value: [ d`${cloudBuildDotNetDirectory.path}` ] },
{ name: "DOTNET_ROOT", separator: ";", value: d`${cloudBuildDotNetDirectory.path}` },
];
}
return [];
}
/**
* Special command line options for the guardian run command to automatically generate baselines or suppressions
* Note that this will disable breaking the build so that all baselines can be generated without the build stopping early due to a failure.
*/
function getBaselineOrSuppressOptions(args : GuardianArguments) : Argument[] {
if (Environment.getFlag(guardianGenerateBaselines)) {
return [
Cmd.argument("--not-break-on-detections"),
Cmd.option("--output-baseline-file ", p`${args.autoGeneratedBaselineSuppressionLocation.path}/${args.baselineFileName}`),
];
}
else if (Environment.getFlag(guardianGenerateSuppressions)) {
return [
Cmd.argument("--not-break-on-detections"),
Cmd.option("--output-suppression-file ", p`${args.autoGeneratedBaselineSuppressionLocation.path}/${args.suppressionFileName}`),
];
}
return [];
}
/**
* Set of guardian arguments. See notes on each argument for any special considerations that need to be
* taken before using them.
@ -445,8 +535,31 @@ export interface GuardianArguments extends Transformer.RunnerArguments {
severity?: string;
/** Do not apply any policy */
noPolicy?: boolean;
/** Log level for Guardian to display to stdout */
logLevel?: GuardianLogLevel;
/** Environment variables to be passed to Guardian */
environmentVariables?: Transformer.EnvironmentVariable[];
/** Location to place automatically generated baselines/suppressions */
autoGeneratedBaselineSuppressionLocation?: Directory;
/** Name for automatically generated baseline file */
baselineFileName?: PathAtom;
/** Name for automatically generated suppression file */
suppressionFileName?: PathAtom;
}
/**
* Guardian Log levels:
*
* None: (Silent) Do not output any messages, even if they are breaking.
* Standard: Standard messages intended for the user to see.
* Verbose: Messages for lower level actions a user may like to see, but are not necessary for them to understand the high level actions of the application.
* Warning: Non-breaking messages that are of greater importance for the user to see. Note: setting Warning also includes Error.
* Error: Breaking message that indicate something went wrong.
* Trace: Messages primarily intended for the application developer or a savy user to debug an application when it faults or gain insight during testing. Messages at this level should not be localized.
*/
@public
export type GuardianLogLevel = "None" | "Standard" | "Verbose" | "Warning" | "Error" | "Trace";
/**
* Collection of Paths that are produced or consumed by Guardian.
*/

Просмотреть файл

@ -0,0 +1,13 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import * as Deployment from "Sdk.Deployment";
@@public
export const deployment : Deployment.Definition = {
contents: [
f`Tool.Guardian.dsc`,
f`Tool.Guardian.CredScan.dsc`,
{file: f`LiteralFiles/module.config.dsc.literal`, targetFileName: a`module.config.dsc`},
]
};

Просмотреть файл

@ -8,7 +8,8 @@ namespace StandardSdk.Guardian {
testFiles: globR(d`.`, "Test.*.dsc"),
sdkFolders: [
d`${Context.getMount("SdkRoot").path}/Tools/Guardian`,
d`${Context.getMount("SdkRoot").path}/Json`
d`${Context.getMount("SdkRoot").path}/Json`,
d`${Context.getMount("SourceRoot").path}/Public/Sdk/Public/Deployment`,
],
// autoFixLkgs: true // Uncomment this line to have all lkgs automatically updated.
});

Просмотреть файл

@ -93,6 +93,8 @@ Transformer.execute({
p`./UserProfile/.nuget/plugins/netcore/CredentialProvider.Microsoft`,
p`./UserProfile/.nuget/packages`,
p`./path/to/guardian/packages`,
p`./path/to/guardian/temp`,
p`./path/to/guardian/tmp`,
p`\${Context.getMount('Windows').path}`,
p`\${Context.getMount('InternetCache').path}`,
p`\${Context.getMount('InternetHistory').path}`,
@ -194,6 +196,8 @@ Transformer.execute({
p`./UserProfile/.nuget/plugins/netcore/CredentialProvider.Microsoft`,
p`./UserProfile/.nuget/packages`,
p`./path/to/guardian/packages`,
p`./path/to/guardian/temp`,
p`./path/to/guardian/tmp`,
p`\${Context.getMount('Windows').path}`,
p`\${Context.getMount('InternetCache').path}`,
p`\${Context.getMount('InternetHistory').path}`,
@ -298,6 +302,8 @@ Transformer.execute({
p`./UserProfile/.nuget/plugins/netcore/CredentialProvider.Microsoft`,
p`./UserProfile/.nuget/packages`,
p`./path/to/guardian/packages`,
p`./path/to/guardian/temp`,
p`./path/to/guardian/tmp`,
p`\${Context.getMount('Windows').path}`,
p`\${Context.getMount('InternetCache').path}`,
p`\${Context.getMount('InternetHistory').path}`,

Просмотреть файл

@ -6,8 +6,9 @@ namespace StandardSdk.Json {
export const hashingTest = BuildXLSdk.sdkTest({
testFiles: globR(d`.`, "Test.*.dsc"),
sdkFolders: [
d`${Context.getMount("SdkRoot").path}/Json`
d`${Context.getMount("SdkRoot").path}/Json`,
d`${Context.getMount("SourceRoot").path}/Public/Sdk/Public/Deployment`,
],
autoFixLkgs: true, // Uncomment this line to have all lkgs automatically updated.
// autoFixLkgs: true, // Uncomment this line to have all lkgs automatically updated.
});
}

Просмотреть файл

@ -73,6 +73,18 @@ function createSdkDeploymentDefinition(serverDeployment: boolean, evaluationOnly
importFrom("Sdk.JavaScript").deployment
]
},
{
subfolder: "Sdk.Json",
contents: [
importFrom("Sdk.Json").deployment
]
},
{
subfolder: "Sdk.Guardian",
contents: [
importFrom("BuildXL.Tools.Guardian").deployment
]
},
])
]
}

Просмотреть файл

@ -0,0 +1 @@
This empty directory is required for Guardian to run on a repo that does not have Guardian initialized.

Просмотреть файл

@ -0,0 +1,10 @@
import * as Guardian from "Sdk.Guardian";
import {Transformer} from "Sdk.Transformers";
// Partially seal Guardian directory because Guardian may write temp files under the root directory
const guardianDirectory : Directory = d`${Environment.getPathValue("TOOLPATH_GUARDIAN")}/gdn`;
const guardianTool : StaticDirectory = Transformer.sealPartialDirectory(guardianDirectory, globR(guardianDirectory, "*"));
// Guardian arguments will be automatically set by the SDK
export const guardianCredScanResult = Guardian.runCredScanOnEntireRepository(guardianTool, d`${Context.getMount("EnlistmentRoot").path}`);

Просмотреть файл

@ -0,0 +1,33 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
config({
resolvers: [
{
kind: "DScript",
modules: [
{ moduleName: "GuardianBuild", projects: [f`GuardianBuild.dsc`] }
]
},
],
mounts: [
{
// This config file may not be in the same directory as the enlistment root
name: a`EnlistmentRoot`,
isReadable: true,
isWritable: true,
isScrubbable: false,
path: Environment.getPathValue("BUILDXL_ENLISTMENT_ROOT"),
trackSourceFileChanges: true
},
{
// The Guardian tool path on Cloudbuild contains the Guardian/GDNP packages, Guardian tool packages, and dotnet binaries
name: a`GuardianToolPath`,
isReadable: true,
isWritable: true,
isScrubbable: false,
path: Environment.getPathValue("TOOLPATH_GUARDIAN"),
trackSourceFileChanges: true
}
]
});

Просмотреть файл

@ -0,0 +1,35 @@
{
"fileVersion": "1.4",
"tools": [
{
"fileVersion": "1.4",
"tool": {
"name": "CredScan",
"version": "2.1.17"
},
"arguments": {
"TargetDirectory": "$(WorkingDirectory)/guardian.TSV",
"OutputType": "pre",
"SuppressAsError": true
},
"outputExtension": "xml",
"successfulExitCodes": [
0,
2,
4,
6
],
"errorExitCodes": {
"1": "Partial scan completed with warnings.",
"3": "Partial scan completed with credential matches and warnings.",
"5": "Partial scan completed with application warnings and credential matches",
"7": "Partial scan completed with application warnings, suppressed warnings, and credential matches",
"-1000": "Argument Exception.",
"-1100": "Invalid configuration.",
"-1500": "Configuration Exception.",
"-1600": "IO Exception.",
"-9000": "Unexpected Exception."
}
}
]
}