Merge pull request #553 from h0x0er/feat/container-workflows

self-hosted: refactored block-policy apply logic
This commit is contained in:
Varun Sharma 2025-06-05 00:17:06 -07:00 committed by GitHub
commit a9da90b635
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 79 additions and 72 deletions

View file

@ -39,7 +39,7 @@ jobs:
run: npm test -- --coverage
- uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
- name: Publish Test Results
uses: step-security/publish-unit-test-result-action@cc82caac074385ae176d39d2d143ad05e1130b2d # v2.18.0
uses: step-security/publish-unit-test-result-action@b495e9a82021fc8f34737416de688298581b847d # v2.19.0
if: always()
with:
files: |

2
dist/index.js vendored
View file

@ -27752,7 +27752,7 @@ function addSummary() {
const STATUS_HARDEN_RUNNER_UNAVAILABLE = "409";
const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner does not run in a container as it needs sudo access to run. This job will not be monitored.";
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
const SELF_HOSTED_RUNNER_MESSAGE = "This job is running on a self-hosted runner.";
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

25
dist/post/index.js vendored
View file

@ -27751,7 +27751,7 @@ function addSummary() {
const STATUS_HARDEN_RUNNER_UNAVAILABLE = "409";
const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner does not run in a container as it needs sudo access to run. This job will not be monitored.";
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
const SELF_HOSTED_RUNNER_MESSAGE = "This job is running on a self-hosted runner.";
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";
@ -27792,7 +27792,7 @@ function isDocker() {
;// CONCATENATED MODULE: ./src/arc-runner.ts
function isArcRunner() {
function isARCRunner() {
const runnerUserAgent = process.env["GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT"];
let isARC = false;
if (!runnerUserAgent) {
@ -27805,20 +27805,27 @@ function isArcRunner() {
}
function isSecondaryPod() {
const workDir = "/__w";
return external_fs_.existsSync(workDir);
let hasKubeEnv = process.env["KUBERNETES_PORT"] !== undefined;
return external_fs_.existsSync(workDir) && hasKubeEnv;
}
function sendAllowedEndpoints(endpoints) {
const startTime = Date.now();
const allowedEndpoints = endpoints.split(" "); // endpoints are space separated
for (const endpoint of allowedEndpoints) {
if (endpoint) {
let sent = 0;
for (let endpoint of allowedEndpoints) {
endpoint = endpoint.trim();
if (endpoint.length > 0) {
let encodedEndpoint = Buffer.from(endpoint).toString("base64");
let endpointPolicyStr = `step_policy_endpoint_${encodedEndpoint}`;
echo(endpointPolicyStr);
sent++;
}
}
if (allowedEndpoints.length > 0) {
applyPolicy(allowedEndpoints.length);
if (sent > 0) {
applyPolicy(sent);
}
const duration = Date.now() - startTime;
console.log(`[harden-runner] sendAllowedEndpoints completed in ${duration}ms (sent ${sent} endpoints)`);
}
function applyPolicy(count) {
let applyPolicyStr = `step_policy_apply_${count}`;
@ -27897,7 +27904,7 @@ var cleanup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _
console.log(CONTAINER_MESSAGE);
return;
}
if (isArcRunner()) {
if (isARCRunner()) {
console.log(`[!] ${ARC_RUNNER_MESSAGE}`);
return;
}
@ -27952,7 +27959,7 @@ var cleanup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _
try {
var journalLog = external_child_process_.execSync("sudo journalctl -u agent.service --lines=1000", {
encoding: "utf8",
maxBuffer: 1024 * 1024 * 10 // 10MB buffer
maxBuffer: 1024 * 1024 * 10, // 10MB buffer
});
console.log("agent.service log:");
console.log(journalLog);

File diff suppressed because one or more lines are too long

41
dist/pre/index.js vendored
View file

@ -87779,7 +87779,7 @@ function addSummary() {
const STATUS_HARDEN_RUNNER_UNAVAILABLE = "409";
const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner does not run in a container as it needs sudo access to run. This job will not be monitored.";
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
const SELF_HOSTED_RUNNER_MESSAGE = "This job is running on a self-hosted runner.";
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";
@ -87920,7 +87920,7 @@ var cacheUtils = __nccwpck_require__(1518);
;// CONCATENATED MODULE: ./src/arc-runner.ts
function isArcRunner() {
function isARCRunner() {
const runnerUserAgent = process.env["GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT"];
let isARC = false;
if (!runnerUserAgent) {
@ -87933,20 +87933,27 @@ function isArcRunner() {
}
function isSecondaryPod() {
const workDir = "/__w";
return external_fs_.existsSync(workDir);
let hasKubeEnv = process.env["KUBERNETES_PORT"] !== undefined;
return external_fs_.existsSync(workDir) && hasKubeEnv;
}
function sendAllowedEndpoints(endpoints) {
const startTime = Date.now();
const allowedEndpoints = endpoints.split(" "); // endpoints are space separated
for (const endpoint of allowedEndpoints) {
if (endpoint) {
let sent = 0;
for (let endpoint of allowedEndpoints) {
endpoint = endpoint.trim();
if (endpoint.length > 0) {
let encodedEndpoint = Buffer.from(endpoint).toString("base64");
let endpointPolicyStr = `step_policy_endpoint_${encodedEndpoint}`;
echo(endpointPolicyStr);
sent++;
}
}
if (allowedEndpoints.length > 0) {
applyPolicy(allowedEndpoints.length);
if (sent > 0) {
applyPolicy(sent);
}
const duration = Date.now() - startTime;
console.log(`[harden-runner] sendAllowedEndpoints completed in ${duration}ms (sent ${sent} endpoints)`);
}
function applyPolicy(count) {
let applyPolicyStr = `step_policy_apply_${count}`;
@ -88242,7 +88249,7 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
if (!confg.disable_telemetry || confg.egress_policy === "audit") {
printInfo(web_url);
}
if (isArcRunner()) {
if (isARCRunner()) {
console.log(`[!] ${ARC_RUNNER_MESSAGE}`);
if (confg.egress_policy === "block") {
sendAllowedEndpoints(confg.allowed_endpoints);
@ -88256,22 +88263,10 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
external_fs_.appendFileSync(process.env.GITHUB_STATE, `selfHosted=true${external_os_.EOL}`, {
encoding: "utf8",
});
if (!external_fs_.existsSync("/home/agent/agent")) {
lib_core.info(SELF_HOSTED_NO_AGENT_MESSAGE);
return;
}
lib_core.info(SELF_HOSTED_RUNNER_MESSAGE);
if (confg.egress_policy === "block") {
try {
if (process.env.USER) {
chownForFolder(process.env.USER, "/home/agent");
}
const confgStr = JSON.stringify(confg);
external_fs_.writeFileSync("/home/agent/block_event.json", confgStr);
yield setup_sleep(5000);
}
catch (error) {
lib_core.info(`[!] Unable to write block_event.json: ${error}`);
}
sendAllowedEndpoints(confg.allowed_endpoints);
yield setup_sleep(5000);
}
return;
}

File diff suppressed because one or more lines are too long

View file

@ -1,9 +1,9 @@
import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
import { isARCRunner } from "./arc-runner";
it("should correctly recognize arc based runner", async () => {
process.env["GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT"] =
"actions-runner-controller/2.0.1";
let isArc: boolean = await isArcRunner();
let isArc: boolean = await isARCRunner();
expect(isArc).toBe(true);
});

View file

@ -2,7 +2,7 @@ import * as cp from "child_process";
import * as fs from "fs";
import path from "path";
export function isArcRunner(): boolean {
export function isARCRunner(): boolean {
const runnerUserAgent = process.env["GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT"];
let isARC = false;
@ -18,23 +18,33 @@ export function isArcRunner(): boolean {
function isSecondaryPod(): boolean {
const workDir = "/__w";
return fs.existsSync(workDir);
let hasKubeEnv = process.env["KUBERNETES_PORT"] !== undefined;
return fs.existsSync(workDir) && hasKubeEnv;
}
export function sendAllowedEndpoints(endpoints: string): void {
const startTime = Date.now();
const allowedEndpoints = endpoints.split(" "); // endpoints are space separated
for (const endpoint of allowedEndpoints) {
if (endpoint) {
let sent = 0;
for (let endpoint of allowedEndpoints) {
endpoint = endpoint.trim();
if (endpoint.length > 0) {
let encodedEndpoint = Buffer.from(endpoint).toString("base64");
let endpointPolicyStr = `step_policy_endpoint_${encodedEndpoint}`;
echo(endpointPolicyStr);
sent++;
}
}
if (allowedEndpoints.length > 0) {
applyPolicy(allowedEndpoints.length);
if (sent > 0) {
applyPolicy(sent);
}
const duration = Date.now() - startTime;
console.log(
`[harden-runner] sendAllowedEndpoints completed in ${duration}ms (sent ${sent} endpoints)`
);
}
function applyPolicy(count: number): void {

View file

@ -2,7 +2,7 @@ import * as fs from "fs";
import * as cp from "child_process";
import * as common from "./common";
import isDocker from "is-docker";
import { isArcRunner } from "./arc-runner";
import { isARCRunner } from "./arc-runner";
import { isGithubHosted } from "./tls-inspect";
(async () => {
console.log("[harden-runner] post-step");
@ -16,7 +16,7 @@ import { isGithubHosted } from "./tls-inspect";
return;
}
if (isArcRunner()) {
if (isARCRunner()) {
console.log(`[!] ${common.ARC_RUNNER_MESSAGE}`);
return;
}
@ -82,13 +82,16 @@ import { isGithubHosted } from "./tls-inspect";
var disable_sudo = process.env.STATE_disableSudo;
var disable_sudo_and_containers = process.env.STATE_disableSudoAndContainers;
if (disable_sudo !== "true" && disable_sudo_and_containers !== "true") {
try {
var journalLog = cp.execSync("sudo journalctl -u agent.service --lines=1000", {
encoding: "utf8",
maxBuffer: 1024 * 1024 * 10 // 10MB buffer
});
var journalLog = cp.execSync(
"sudo journalctl -u agent.service --lines=1000",
{
encoding: "utf8",
maxBuffer: 1024 * 1024 * 10, // 10MB buffer
}
);
console.log("agent.service log:");
console.log(journalLog);
} catch (error) {

View file

@ -173,8 +173,8 @@ export const CONTAINER_MESSAGE =
export const UBUNTU_MESSAGE =
"This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
export const SELF_HOSTED_NO_AGENT_MESSAGE =
"This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
export const SELF_HOSTED_RUNNER_MESSAGE =
"This job is running on a self-hosted runner.";
export const HARDEN_RUNNER_UNAVAILABLE_MESSAGE =
"Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";

View file

@ -24,7 +24,7 @@ import { GetCacheEntryDownloadURLRequest } from "@actions/cache/lib/generated/re
import { getCacheServiceVersion } from "@actions/cache/lib/internal/config";
import * as utils from "@actions/cache/lib/internal/cacheUtils";
import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
import { isARCRunner, sendAllowedEndpoints } from "./arc-runner";
import { STEPSECURITY_API_URL, STEPSECURITY_WEB_URL } from "./configs";
import { isGithubHosted, isTLSEnabled } from "./tls-inspect";
import { installAgent } from "./install-agent";
@ -62,7 +62,9 @@ interface MonitorResponse {
egress_policy: core.getInput("egress-policy"),
disable_telemetry: core.getBooleanInput("disable-telemetry"),
disable_sudo: core.getBooleanInput("disable-sudo"),
disable_sudo_and_containers: core.getBooleanInput("disable-sudo-and-containers"),
disable_sudo_and_containers: core.getBooleanInput(
"disable-sudo-and-containers"
),
disable_file_monitoring: core.getBooleanInput("disable-file-monitoring"),
private: context?.payload?.repository?.private || false,
is_github_hosted: isGithubHosted(),
@ -205,7 +207,7 @@ interface MonitorResponse {
common.printInfo(web_url);
}
if (isArcRunner()) {
if (isARCRunner()) {
console.log(`[!] ${common.ARC_RUNNER_MESSAGE}`);
if (confg.egress_policy === "block") {
sendAllowedEndpoints(confg.allowed_endpoints);
@ -220,22 +222,12 @@ interface MonitorResponse {
fs.appendFileSync(process.env.GITHUB_STATE, `selfHosted=true${EOL}`, {
encoding: "utf8",
});
if (!fs.existsSync("/home/agent/agent")) {
core.info(common.SELF_HOSTED_NO_AGENT_MESSAGE);
return;
}
if (confg.egress_policy === "block") {
try {
if (process.env.USER) {
chownForFolder(process.env.USER, "/home/agent");
}
const confgStr = JSON.stringify(confg);
fs.writeFileSync("/home/agent/block_event.json", confgStr);
await sleep(5000);
} catch (error) {
core.info(`[!] Unable to write block_event.json: ${error}`);
}
core.info(common.SELF_HOSTED_RUNNER_MESSAGE);
if (confg.egress_policy === "block") {
sendAllowedEndpoints(confg.allowed_endpoints);
await sleep(5000);
}
return;
}