flip_api.scripts.register_trust

Register a single trust on the hub and emit its kit (deploy-time CLI).

Invoked once per trust by the deploy Makefile’s register-trust-<n> targets (dev: docker compose exec; prod: a one-off ECS task). The trust’s name / code / region are passed as arguments — the hub carries no trust list of its own; the deploy tooling decides what to register.

Idempotent: if a trust with --name already exists it is skipped.

Output transports — two contracts depending on --out-ssm-parameter:

  • Default (dev pipe / docker compose exec) — the kit JSON array prints on stdout. Consumed locally by scripts/distribute_trust_kits.py. The pipe is local: no remote storage involved.

  • ``–out-ssm-parameter <name>`` (prod ECS one-off task) — the kit JSON is written to an SSM Parameter Store SecureString at <name>; stdout receives only that parameter name (one ASCII line, safe to capture in CloudWatch). The deploy script then ssm:GetParameter --with-decryption reads the kit out-of-band and ssm:DeleteParameter immediately deletes it. This is the S-1 fix: it keeps plaintext API keys, internal-service keys, and hub_shared.AES_KEY_BASE64 out of CloudWatch entirely (the awslogs driver only sees the parameter name, never the kit body).

Kit shape (both transports):

  • New registration: full kit (trust_id, trust_name, trust_api_key, trust_internal_service_key, fl_kit_slot, fl_kit_slot_number, hub_shared).

  • Idempotent skip (trust already existed): metadata-only kit (same keys minus trust_api_key / trust_internal_service_key). The hub stores only the SHA-256 hashes of those keys and cannot re-emit plaintext, so credentials are intentionally absent on the skip path.

Both shapes include hub_shared so the deploy distributor can sync shared env values without rotating credentials.

  • stderr — human-readable logging (does not contain the kit body).

  • Exit code 0 on success or skip; 1 on a registration or transport failure.

Attributes

HUB_SHARED_ENV_KEYS

Functions

_hub_shared_from_env(→ dict[str, str])

Read hub-shared values from os.environ. Unset keys are omitted (no empty strings).

register_one_trust(→ list[dict[str, Any]])

Register one trust if it does not already exist.

_write_kit_to_ssm(→ None)

Write the kit JSON to an SSM Parameter Store SecureString.

main(→ None)

CLI entry point: register one trust, emit its kit JSON to the chosen output.

Module Contents

flip_api.scripts.register_trust.HUB_SHARED_ENV_KEYS = ('AES_KEY_BASE64', 'CENTRAL_HUB_API_URL', 'TRUST_API_KEY_HEADER', 'FL_BACKEND',...
flip_api.scripts.register_trust._hub_shared_from_env() dict[str, str]

Read hub-shared values from os.environ. Unset keys are omitted (no empty strings).

flip_api.scripts.register_trust.register_one_trust(name: str, code: str | None, region: str | None, session: sqlmodel.Session, require_existing: bool = False) list[dict[str, Any]]

Register one trust if it does not already exist.

Parameters:
  • name (str) – Trust display name.

  • code (str | None) – Short code (e.g. GSTT). Required when registering a new trust — register_trust raises EmptyTrustCodeError on a blank code. Unused on the idempotent-skip / require_existing paths.

  • region (str | None) – Optional NHS region.

  • session (Session) – SQLModel session.

  • require_existing (bool) – When True, exit with an error if the trust has not yet been registered. Prevents sync-trust-kit-N from silently minting and discarding credentials for an unregistered trust.

Returns:

[kit] always — one full kit dict (including credentials) for a new registration, or one metadata-only dict (no credentials) when the trust already existed (idempotent skip). Both shapes include a hub_shared key populated from os.environ so the deploy distributor can sync shared values without rotating credentials.

Return type:

list[dict[str, Any]]

Raises:
  • TrustRegistrationError – If registration of a new trust fails.

  • SystemExit – If require_existing is True and the trust does not exist.

flip_api.scripts.register_trust._write_kit_to_ssm(kits: list[dict[str, Any]], parameter_name: str) None

Write the kit JSON to an SSM Parameter Store SecureString.

The deploy script (register-trusts.sh) mints the parameter name before spawning this CLI as a one-off ECS task, then reads + deletes it after the task completes. The ECS task role only needs ssm:PutParameter on this path; SecureString encryption uses the AWS-managed alias/aws/ssm so no extra KMS permissions are required.

Overwrite=True is intentional — re-runs of register-trusts.sh may reuse a parameter name on retry. Idempotent registration emits the same metadata-only kit, so overwriting is safe.

Parameters:
  • kits (list[dict[str, Any]]) – The kit list to persist (always length 1).

  • parameter_name (str) – SSM parameter name (must start with /).

Raises:

SystemExit – If the SSM put fails — the deploy script must NOT proceed on a partial write, since the credentials block in kits is unrecoverable from the hub side once the session is committed.

flip_api.scripts.register_trust.main() None

CLI entry point: register one trust, emit its kit JSON to the chosen output.