lablup / lablup/backend.ai

Provide a stable credential-introspection / signature-delegation API for satellite services (replace legacy-GQL `secret_key` reads)

Open
#12,829 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
670
Forks
183
Avg merge
17h 7m
Merged PRs (30d)
358

Description

## Problem

Satellite services that terminate AWS-SigV4 (or other keypair-signed) traffic on behalf of users — e.g. an S3-compatible gateway over vfolders — must verify a request's signature, which today requires resolving a Backend.AI access key to its **secret key**. The only queryable path for that is the **legacy graphene** GraphQL schema:

- `keypair(access_key) { secret_key }` — field at `manager/api/gql_legacy/schema.py:793` (resolver `:2036`), `KeyPair.secret_key` populated from the DB row at `gql_legacy/keypair.py:103,166`.

The **new Strawberry** schema deliberately exposes `secret_key` **only once at creation** (`api/gql/keypair/types/payloads.py`: "The secret_key is only shown once"). That is a strong signal the queryable form will not survive the legacy schema's retirement, which would break every satellite service that depends on it — with no migration path.

## Request

A stable, supported API for signature verification by trusted satellite services, in preference order:

1. **Signature-delegation endpoint (preferred).** The service submits the SigV4 `string-to-sign` (or canonical request) + access key ID + claimed scope; the Manager answers `valid/invalid` **plus the resolved user identity** (user UUID, active state, rate-limit class). This keeps secrets entirely inside the Manager — the satellite service never holds them, eliminating the secret-cache exfiltration surface.
2. **Least-privilege secret-fetch endpoint (fallback).** A supported "resolve secret + identity + active-state for AKID" call on the new schema, scoped to a dedicated role (see ask #2), replacing the legacy-GQL read.

Either should return, atomically, the **owning user's active state** (not just the keypair's `is_active`) — a deactivated user can still own an active keypair.

## Rationale

- BAIFS's entire auth strategy currently rests on the legacy field; its removal is the project's top external risk.
- A delegation endpoint is strictly better than any secret-fetch: it removes plaintext secrets from satellite memory, and it lets the Manager keep full control of rotation/revocation semantics.
- This benefits any future keypair-signed satellite (SFTP, WebDAV, other gateways), not only BAIFS.

## Citations (`6d680960d`)

- `manager/api/gql_legacy/schema.py:793`, resolver `:2036`; `gql_legacy/keypair.py:103,166` (legacy `secret_key` read).
- `api/gql/keypair/types/payloads.py` (new schema returns `secret_key` once at creation).
- Verifier the delegation endpoint would encapsulate: `manager/api/rest/middleware/auth.py:377-416` (`sign_request`), constant-time compare at `:610`.

---
_Filed from the BAIFS project: see lablup/BAIFS#6 and `docs/spikes/upstream-asks/01-credential-resolution-api.md` for full context and citations._

Contributor guide

Open the contributing guide

Research direction

Start with the legacy keypair field and resolver in manager/api/gql_legacy/schema.py and gql_legacy/keypair.py, then read the new payload definition in api/gql/keypair/types/payloads.py. Review the request-signing verifier in manager/api/rest/middleware/auth.py and the cited BAIFS design document. Done means a supported API design and implementation path replaces legacy secret_key reads while returning the owning user's active state.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
api, authentication, backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.