cellmap_flow.ai_annotate.secrets ================================ .. py:module:: cellmap_flow.ai_annotate.secrets .. autoapi-nested-parse:: Keeping provider secrets out of logs, and reading API keys safely. The dashboard streams the ``cellmap_flow`` logger to the browser (``/api/logs/stream``), so anything logged is as good as shown to whoever has the page open. Every secret this process reads is registered here, and a logging filter replaces registered values with ``[REDACTED]`` in each record before a handler formats it: the message, its arguments, and the traceback text, since an SDK exception's message is where a key is most likely to turn up. Vertex AI uses Application Default Credentials, so it has no key and registers nothing. ``resolve_api_key`` is for key-based providers: the key comes from an environment variable or from a file only the user can read, never from the config file, and it is read at call time, not kept in session state. Attributes ---------- .. autoapisummary:: cellmap_flow.ai_annotate.secrets.REDACTED cellmap_flow.ai_annotate.secrets.MIN_SECRET_LENGTH cellmap_flow.ai_annotate.secrets.CLOUD_PLATFORM_SCOPE Classes ------- .. autoapisummary:: cellmap_flow.ai_annotate.secrets.RedactingFilter Functions --------- .. autoapisummary:: cellmap_flow.ai_annotate.secrets.register_secret cellmap_flow.ai_annotate.secrets.redact cellmap_flow.ai_annotate.secrets.install_log_redaction cellmap_flow.ai_annotate.secrets.resolve_api_key cellmap_flow.ai_annotate.secrets.load_google_credentials Module Contents --------------- .. py:data:: REDACTED :value: '[REDACTED]' .. py:data:: MIN_SECRET_LENGTH :value: 8 .. py:function:: register_secret(value) Redact ``value`` from every log record from now on. Values shorter than eight characters are ignored. The URL-quoted form is registered too, as an HTTP library logging a request URL would quote a key passed as a query parameter. .. py:function:: redact(text) ``text`` with every registered secret replaced by ``[REDACTED]``. .. py:class:: RedactingFilter(name='') Rewrites a log record so no registered secret survives formatting. The message is formatted with its arguments first and the result redacted, because a secret is as likely to arrive as an argument (``"%s", exc``) as in the format string; the record then carries the finished text and no arguments. The traceback is formatted here too (``exc_text``), which ``logging.Formatter`` uses as is instead of formatting it again. The record is changed in place, so every handler after this one -- the terminal's included -- sees the redacted version. .. py:method:: filter(record) Determine if the specified record is to be logged. Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place. .. py:function:: install_log_redaction(logger) Add the redacting filter to ``logger`` and to each of its handlers. Both, because a logger's own filters see only records logged on that logger by name; a record from a child (``cellmap_flow.dashboard.x``) reaches the package logger's handlers without passing its filters. Calling this again adds nothing twice; a handler added later needs another call. .. py:function:: resolve_api_key(options) A key-based provider's API key, from ``api_key_env`` or ``api_key_file``. None when the provider names neither (Vertex AI, which uses Application Default Credentials). The value is registered for redaction before it is returned, and is never logged. A key file must be a regular file owned by the current user with no group or world permission bits (``chmod 600``), the rule ssh applies to private keys: a key others can read is a key others can spend. An inline ``api_key`` is refused here as well as in the config loader, so a caller that skipped the loader cannot use one. .. py:data:: CLOUD_PLATFORM_SCOPE :value: 'https://www.googleapis.com/auth/cloud-platform' .. py:function:: load_google_credentials(path) Google credentials from a credentials file the config names (``credentials_file``). The file is what ``gcloud auth application-default login`` writes (a refresh token) or a service account's key. Naming it in the config, and keeping it on storage every cluster node mounts, means the dashboard signs in the same way wherever it runs, with nothing to export first. The file is held to the API key rule (``_read_private_file``): owned by you, readable by you alone. Its secret fields are registered for redaction, and the credentials go straight to the Google SDK; nothing from the file is kept, logged or sent to the browser.