-
Notifications
You must be signed in to change notification settings - Fork 26
Feature/action transient secrets #1699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cohansen
wants to merge
13
commits into
develop
Choose a base branch
from
feature/action-transient-secrets
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
9fe7f64
Added transient secrets to the actions server
cohansen f05d3ad
Refactored actions with secrets to be executed via a callback
cohansen 5001d2f
Renamed secrets to has_secrets
cohansen 4747499
Fixed action-server tests and added a secret test
cohansen 719e0c9
Moved the secrets db migration to 24
cohansen 9ef9d49
Added table context to drop triggers
cohansen d21f4d7
Updated to use the newest version of aerie actions
cohansen 8a44d23
Moved transient secrets to migration 25
cohansen 9b35f90
merge develop into feature/feature/action-transient-secrets and resol…
dandelany 4bc7992
update migration numbers for action secrets migration (27)
dandelany 50860ac
avoid overwriting value of secrets variable in action-server codeRunner
dandelany 46c4373
remove action run queue/secrets objects with Map for better key safety
dandelany cfcff04
More actionRunner improvements
cohansen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,23 @@ | ||
import { sheriff, tseslint } from 'eslint-config-sheriff'; | ||
import { sheriff, tseslint } from "eslint-config-sheriff"; | ||
|
||
const sheriffOptions = { | ||
"react": false, | ||
"lodash": false, | ||
"remeda": false, | ||
"next": false, | ||
"astro": false, | ||
"playwright": false, | ||
"jest": false, | ||
"vitest": false | ||
react: false, | ||
lodash: false, | ||
remeda: false, | ||
next: false, | ||
astro: false, | ||
playwright: false, | ||
jest: false, | ||
vitest: false, | ||
}; | ||
|
||
export default tseslint.config(sheriff(sheriffOptions), | ||
{ | ||
rules: { | ||
"@typescript-eslint/no-explicit-any": ["off"] | ||
}, | ||
}, | ||
); | ||
export default tseslint.config(sheriff(sheriffOptions), { | ||
rules: { | ||
"@typescript-eslint/no-explicit-any": ["off"], | ||
"@typescript-eslint/no-extraneous-class": "off", | ||
"@typescript-eslint/naming-convention": "off", | ||
"func-style": "off", | ||
"no-restricted-syntax": "off", | ||
"@typescript-eslint/no-dynamic-delete": "off", | ||
}, | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { runAction } from "../listeners/dbListeners"; | ||
import logger from "../utils/logger"; | ||
import type { ActionRunInsertedPayload } from "./types"; | ||
|
||
export class ActionRunner { | ||
// Wait up to 10 minutes for the action run associated with the secrets. | ||
private static WAIT_FOR_ACTION_RUN_TIMEOUT = 600000; | ||
// Wait up to 1 minute for the secrets associated with the action run. | ||
private static WAIT_FOR_SECRET_TIMEOUT = 60000; | ||
|
||
private static actionRuns: Record<string, ActionRunInsertedPayload> = {}; | ||
private static actionRunQueue: Map<string, (actionRunId: string) => Promise<void>> = new Map(); | ||
private static actionSecretsMap: Map<string, Record<string, string>> = new Map(); | ||
|
||
static async addActionRun(actionRun: ActionRunInsertedPayload): Promise<void> { | ||
const actionRunId = actionRun.action_run_id; | ||
|
||
this.actionRuns[actionRunId] = actionRun; | ||
const actionRunFunc = async (runId: string) => { | ||
try { | ||
await ActionRunner.runAction(runId); | ||
this.deleteActionRun(runId); | ||
} catch (error) { | ||
this.deleteActionRun(runId); | ||
} | ||
}; | ||
|
||
this.actionRunQueue.set(actionRunId, actionRunFunc); | ||
|
||
// If there aren't any secrets execute the action run immediately. | ||
if (!actionRun.has_secrets) { | ||
await actionRunFunc(actionRunId); | ||
} else { | ||
logger.info(`Action Run: ${actionRunId} waiting for secrets...`); | ||
} | ||
|
||
setTimeout(() => { | ||
if (this.actionRunQueue.get(actionRunId) !== null) { | ||
logger.info(`Action Run: ${actionRunId} timed out waiting for the associated action secrets.`); | ||
this.deleteActionRun(actionRunId); | ||
} | ||
}, this.WAIT_FOR_SECRET_TIMEOUT); | ||
} | ||
|
||
static async addActionSecret(actionRunId: string, actionSecrets: Record<string, string>): Promise<void> { | ||
this.actionSecretsMap.set(actionRunId, actionSecrets); | ||
|
||
logger.info(`Secret found for Action Run: ${actionRunId}, running action...`); | ||
Check warningCode scanning / CodeQL Log injection Medium
Log entry depends on a
user-provided value Error loading related location Loading |
||
|
||
const actionRunFunc = this.actionRunQueue.get(actionRunId); | ||
|
||
if (actionRunFunc) { | ||
setTimeout(() => { | ||
if (this.actionSecretsMap.get(actionRunId) !== null) { | ||
logger.info(`Secret for Action Run: ${actionRunId} timed out waiting for the associated action run.`); | ||
Check warningCode scanning / CodeQL Log injection Medium
Log entry depends on a
user-provided value Error loading related location Loading |
||
this.deleteActionSecret(actionRunId); | ||
} | ||
}, this.WAIT_FOR_ACTION_RUN_TIMEOUT); | ||
|
||
await actionRunFunc(actionRunId); | ||
Check failureCode scanning / CodeQL Unvalidated dynamic method call High
Invocation of method with
user-controlled Error loading related location Loading |
||
this.deleteActionSecret(actionRunId); | ||
} else { | ||
throw new Error(`Action Run ${actionRunId} not found in queue`); | ||
} | ||
} | ||
|
||
static deleteActionRun(actionRunId: string): void { | ||
delete this.actionRuns[actionRunId]; | ||
this.actionRunQueue.delete(actionRunId); | ||
} | ||
|
||
static deleteActionSecret(actionRunId: string): void { | ||
this.actionSecretsMap.delete(actionRunId); | ||
} | ||
|
||
private static async runAction(actionRunId: string): Promise<void> { | ||
const action = this.actionRuns[actionRunId]; | ||
const secret = action.has_secrets ? this.actionSecretsMap.get(actionRunId) : undefined; | ||
|
||
this.deleteActionRun(actionRunId); | ||
this.deleteActionSecret(actionRunId); | ||
|
||
await runAction(action, secret); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.