Skip to content

Mint a per-job API key for the submitter of an action Batch job - #484

Draft
accumb3ns wants to merge 2 commits into
mainfrom
feature/launcher-user-api-key
Draft

accumb3ns wants to merge 2 commits into
mainfrom
feature/launcher-user-api-key

Conversation

@accumb3ns

Copy link
Copy Markdown
Contributor

Why

Some Batch jobs call back into NGS360 as the user who started them. The case driving this is a pipeline launcher running as an AWS Batch job: for up to the job's timeout, it submits and watches child WES runs, looks up the project and uploads its results list. A session token expires long before that, so today the job has to be handed a long-lived credential by hand.

The chat agent's delegated token doesn't fit here either. It is a 5-minute JWT, and it can't be revoked once the job finishes. An ngs360_ API key already has what a job credential needs: an expiry, immediate revocation, and a row that stays auditable after retirement.

What changed

  • aws_batch.user_api_key_hours is a new optional field on action configs, from 1 to 168 hours. When it is set, POST /projects/{id}/actions/submit does the following:
  • Every call the job makes is authorized against the submitter's own roles and project memberships, restricted projects included, exactly as if they had made it.
  • Safeguards:
    • The key is minted only from the authenticated user object, never from a username string. (POST /jobs takes user from the request body, so a lookup by name there would mint someone else's key.)
    • The field lives on an action-only subclass of AwsBatchConfig, so POST /jobs and tool configs can't request a key.
  • Log masking: submit_batch_job used to log the full container overrides, environment included. Values whose names look like credentials (TOKEN, KEY, SECRET, PASSWORD) are now masked in that log line. This commit comes first, so no commit in the series logs a minted key.

Configs that don't set the field behave exactly as before.

Known limits

  • The key is visible in the job description. It travels in Batch containerOverrides.environment, so anyone with batch:DescribeJobs can read it until it is retired or expires. Moving it to a per-job Secrets Manager secret would remove that exposure; it's left as a follow-up.
  • A killed job leaves its key active until it expires. Retiring keys from the existing Batch state-change path would close that gap; also a follow-up.
  • No UI path launches a launcher yet. ActionPlatform is still Arvados/SevenBridges only, so this supplies the credential and launch wiring comes separately.

Testing

  • Four new tests:
    • a key is minted, owned by the submitter, named for the job, and expires at the configured time;
    • a config without the field mints nothing;
    • the key is revoked when AWS Batch refuses the job;
    • credential values are masked in the logged overrides.
  • uv run pytest: 1525 passed.
  • flake8 api tests: clean.

🤖 Generated with Claude Code

vasques1 and others added 2 commits October 28, 2026 09:42
submit_batch_job logged the full container overrides, environment
included, so any credential passed to a job reached this service's logs
in plain text. Values whose names look like credentials (TOKEN, KEY,
SECRET, PASSWORD) are now masked in the log line; the overrides sent to
AWS Batch are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ig asks

A job that calls back into NGS360 as the user who started it -- a
pipeline launcher overseeing its own child runs -- outlives any session
token that user holds, and until now had to be handed a long-lived
credential by hand.

An action config can now set aws_batch.user_api_key_hours. On submit,
APIServer mints an ngs360_ API key owned by the authenticated submitter,
expiring after that many hours, and injects it as NGS360_AUTH_TOKEN with
its id as NGS360_AUTH_KEY_ID so the job can retire it on exit. Every call
the job makes is then authorized against the submitter's own roles and
project memberships. The key is renamed for the Batch job id once there
is one, and revoked if AWS Batch refuses the job.

The key is minted only from the authenticated user, never from a
username string, and the field lives on the action-only batch config so
POST /jobs and tool configs cannot ask for one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant