bigfix-remote-session-relevance
Evaluate BigFix session relevance through the root server REST API, BigFix Explorer, the Web Reports SOAP API, or BigFix SaaS, against every configured deployment at once, and get the same result back whichever one answered.
uvx bigfix-remote-session-relevance "number of bes computers"
The session-relevance counterpart to bigfix-remote-client-relevance.
What it does
- One result type. REST (JSON), Explorer (JSON) and Web Reports (SOAP
XML) all return a
SessionRelevanceResultwith native answers (int,bool,str, tuples), the type string, plurality and evaluation time. Callers never see the wire format;result.rawhas it when asked for. - Consistent errors. Relevance errors, bad credentials, unreachable hosts
and login pages come back as results with
error.kindset. The kind and message are the same on every backend. - Many servers. Any number of root servers, Explorers and Web Reports
servers. Connections to the same deployment are recognized automatically
(
sha256 of gather url of bes license), and by default each deployment is queried once, concurrently, with failover between its connections. - Trust on first use for self-signed BigFix certificates: confirm a certificate once (now, or later for GUIs) and it is pinned. A changed certificate is a hard error, and no credentials reach it.
- Auth: Basic or bearer token (11.0.6+ "API key") for REST and Explorer, mTLS client certificates for Explorer, username/password for Web Reports. BigFix SaaS signs in with email/password (TOTP prompted when required).
- Explorer extras (
keys,filters) are additive and opt in. - Async first, with an equally capable sync API. Pure-Python dependencies only.
Setup
uvx bigfix-remote-session-relevance --setup
The wizard asks for a host, username and password, probes the REST API
(52311), Explorer (9383) and Web Reports (443/8083/80/8080), pins
certificates after showing their fingerprints, and writes
~/.bigfix/.remote_session_connections.toml (mode 0600). A host entered
with a port (bes-root.local:52311) is probed only on that port: every
backend over https, plus Web Reports over http. One entered as https://
is probed only over https (Web Reports still on 443 and 8083), and
http:// probes only Web Reports.
Every file the library reads or writes (the connections, pinned
certificates, and the local root server's cached deployment id) lives in
~/.bigfix, or in $BFRSR_HOME when that is set. A sandboxed app (iOS,
Android) sets it once at startup to its own data directory, e.g.
os.environ["BFRSR_HOME"] = str(app_support_dir); data_dir() returns the
directory in use. $BFRSR_CONFIG (or --config) still picks the connections
file itself, and a KnownCerts(path) its own pin file. ~/.besapi.conf,
which belongs to besapi, is always read from the real home directory.
When the REST API answers, setup also asks the root server for the Explorer
and Web Reports servers registered with it (/api/explorers,
/api/webreports), so ones on other machines can be found. It shows the
ones it has not already tried and asks before sending your username and
password to them (default no). Those reached over http:// are marked
cleartext. If you agree, they are probed with the same certificate prompts,
marked "listed by the root server", and offered for saving like the rest.
The root server answers these lists only for a master operator. For anyone
else, setup says so on the REST line and carries on. The lists name a
server as the root server knows it, which can be a short machine name that
does not resolve from where you run setup (it then shows as unreachable),
or the root server's own Explorer under a second name. Setup that probes
only Explorer or Web Reports (run_setup(backends=...) without rest)
never reads the lists.
For BigFix SaaS, enter login.bigfix.com (or eulogin.bigfix.com) as the
host, then your email and password; a TOTP code is asked for only if your
account uses MFA. Setup signs in once and saves one connection per BigFix
server your account can reach. A rejected sign-in is never retried or saved:
BigFix SaaS locks an account after 100 failed logins. See
remote_session_connections.example.toml
for every option. server is normally just a host name: https:// and the
backend's default port are assumed.
Passwords can live in the file, in environment variables named by
password_env, or in this machine's OS password store.
Saved BigFix SaaS sessions
A BigFix SaaS sign-in is saved and reused by later runs, so an account
that uses MFA needs a TOTP code only about once a week: BigFix SaaS ends
every session 7 days after its sign-in, and refreshing does not extend
that. Run --setup (or any run from a terminal) when the code is needed
again; a run with no one to type it fails with totp_required and says so.
BigFix SaaS has no API key or service account, so this is the only way to
run an MFA account unattended.
- The session (the access and refresh tokens, never the password or a TOTP
code) is saved in this machine's password store when it has one (macOS
Keychain, Windows Credential Manager, the iOS Keychain, Linux Secret
Service with the
[keyring]extra). Otherwise it goes in.remote_session_saas_sessions.tomlin~/.bigfix(or$BFRSR_HOME, or the path in$BFRSR_SAAS_SESSIONS) as plaintext with mode 600, like a password in the config file; on Windows that file inherits the folder's permissions. - It belongs to the account (API host and email), so every connection of that account shares it, and a run that has a session sends no password.
- Turn it off for one connection with
session_cache = false, or for everything withBFRSR_SESSION_CACHE=0. --forget-session NAMEdeletes a connection's saved session, so the next run signs in again.- Tokens never appear in output, logs, results or
--show-config, which shows onlysession_cache: on/off.
Processes using one account at the same time take turns renewing it, under a lock file beside the sessions file, so they don't spend each other's single-use refresh token (one that waits more than 35 s goes ahead, and a refused token then reads the saved session again before signing in). A renewal that fails for a passing reason (a 5xx, a timeout) keeps the saved session for the next try.
Passwords in the OS password store
[[connections]]
name = "lab-root"
backend = "rest"
server = "bf.example.com"
username = "operator"
password_store = "system" # no password in the file
password_store = "system" keeps the password in this machine's own store:
the macOS Keychain or the Windows Credential Manager (through
keyring, installed with this package
there), the iOS app Keychain, or on Linux the Secret Service when the
[keyring] extra is installed (uvx --from 'bigfix-remote-session-relevance[keyring]' ...).
The password is looked up in this order: password_env, an inline
password, the store, then a prompt.
The file stays portable. The store entry is keyed by backend, server, port
and username (not the connection name), so the same file lines up with each
machine's own entry. A machine with no store, or no entry for it, just
prompts. So does one whose store fails, such as Windows over key-auth SSH
(error 1312) or a locked keyring: nothing errors, and -v -v logs why. When
the CLI prompts for such a password, it offers to save it in the store
(default no). The password is written only after the server accepts it, so
a typo is never saved. A stored password that has since changed fails with
an authentication error; --forget-password NAME clears it.
--setupasks "Save the password in instead of the config file?" when this machine has a store. The answer defaults to no, which keeps today's file. On yes, the file getspassword_store = "system"and no password. If the store then fails, setup asks again: config file or environment variable.--show-configshowspassword: macOS Keychain(the store's name), and never the secret.--forget-password NAMEdeletes that connection's entry from the store.- Windows entries use "local machine" persistence, so they don't roam with a roaming profile.
- keyring's own settings still apply. For example,
PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyringturns the store off.
Apps pass their own store as secrets= to AsyncSessionRelevanceClient,
SessionRelevanceClient, backend_from_config or Backend.from_config,
for example MemorySecretStore, KeychainSecretStore(), or an Android
Keystore bridge with name, get, set and delete. secrets=None means
no store. The default is default_secret_store(), which is probed once and
is None when this platform has none. secret_account(conn) is the key:
backend:host:port:username, with a non-https scheme in front
(http+rest:...), so an https password is never sent over plain http.
save_prompted_password= (a callable that gets the store's name and returns
a bool) decides whether a prompted password is saved. It is written once a
response shows the server accepted it. Without the callable, nothing is
ever saved.
On a BigFix root server, no setup is needed. Run as root (Linux) or
Administrator (Windows) and the server's own REST API credentials are used
automatically, as an extra rest connection named local-root-server, the
same way besapi logs in first with them. Linux reads
/var/opt/BESServer/Applications/MasterOperatorCredentials and decrypts the
password with the CryptoUtility next to it; Windows reads
HKLM\SOFTWARE\Wow6432Node\BigFix\Enterprise Server\MFSConfig and decrypts
it with DPAPI. Nothing is written to the config file, and the password never
appears in output or logs (--show-config says local root server). As a
normal user on a root server, or when the password cannot be decrypted, the
connection is left out when anything else is configured. To turn it off, set BFRSR_LOCAL_ROOT_SERVER=0 or
local_root_server = false under [defaults].
CLI
bigfix-remote-session-relevance "names of bes sites" # one answer per line
bigfix-remote-session-relevance --json "ids of bes computers" # list of result objects
bigfix-remote-session-relevance --all "now" # every connection, not one per deployment (= -all, --all-connections)
bigfix-remote-session-relevance --backend webreports --raw "1" # raw server response
bigfix-remote-session-relevance --keep-escapes '"a%09b"' # a%09b: % and control characters as %xx
bigfix-remote-session-relevance --keys "id name" \
"(id of it, name of it) of bes computers" # Explorer extras
echo "number of bes fixlets" | bigfix-remote-session-relevance -
bigfix-remote-session-relevance --show-config # connections, no secrets
bigfix-remote-session-relevance --show-certs | --trust-cert NAME | --forget-cert HOST:PORT
bigfix-remote-session-relevance --forget-password NAME # delete it from the OS password store
bigfix-remote-session-relevance --forget-session NAME # delete a saved BigFix SaaS session
Answers go to stdout; errors and -v metadata go to stderr.
Answer text comes from the server, so plain-text output to a terminal
shows control characters as %xx: ESC, CR, LF, the other C0 controls except
tab, DEL and the C1 controls (0x80–0x9F). An answer can't recolour or clear
your terminal, and an answer containing a newline stays on one line
(x%0ay). % itself is left as is, so %SystemRoot% stays readable; use
--keep-escapes for the unambiguous form, where % is %25. Error messages
on a terminal keep their line breaks but lose the other control characters.
Output to a pipe or file is the answer text as is, one answer per line,
so an answer containing a newline prints as several lines. Use --json when
the answer boundaries matter, or --keep-escapes. --json and --raw are
never changed, terminal or not. A pipe into something that writes to the
terminal (| less -R, | tee /dev/tty) is not escaped either.
Text the output encoding can't hold, such as a lone surrogate (\ud800 in
a JSON answer), is written as \ud800 instead of stopping the run.
Results stream in as each deployment answers (completion order), so a slow
or unreachable server no longer holds up the ones that already finished.
Plain text and --raw stream; --json is one document, so it prints once
everything is in. Exit codes are always decided after the full fan-out.
When several results come back, plain text ends with a summary that collapses identical answers, most common first:
== summary: 3 results, 2 distinct answers
2× 1234
prod-root (rest), dr-root (rest)
1× 87
lab-wr (webreports)
Results are grouped by answers, answer type and error (not timing, backend or server), and identical errors collapse too. The summary only appears when it actually collapses something.
| Exit code | Meaning |
|---|---|
| 0 | every queried deployment answered |
| 1 | a session relevance error; --trust-cert declined, --forget-cert found no pin, --forget-password found no store or no entry, or the store failed, --forget-session found no saved session |
| 2 | nothing reachable, or credentials rejected everywhere; --discover-deployments found no id |
| 3 | partial: some deployments failed |
| 64 | usage or configuration error (including one connection whose settings can't be used), or no connection matched --connection / --backend |
Library
from bigfix_remote_session_relevance import evaluate_session_relevance
for result in evaluate_session_relevance("(id of it, name of it) of bes computers"):
if result.ok:
print(result.connection, result.answers) # ((1, 'host-a'), ...)
else:
print(result.connection, result.error.kind, result.error.message)
from bigfix_remote_session_relevance import AsyncSessionRelevanceClient
async with AsyncSessionRelevanceClient() as client: # default config
results = await client.evaluate("number of bes computers")
results.raise_for_error() # opt into exceptions
async for result in client.evaluate_stream("number of bes computers"):
print(result.connection, result.answers) # as each deployment answers
keyed = await client.evaluate_explorer(
"(id of it, name of it) of bes computers", keys="id name"
)
integer and boolean answers are int and bool; every other type
(floating point, date, version, time interval, …) is text, the same
on REST, Explorer and Web Reports (a time from Web Reports is converted
from ISO 8601 to the BigFix form the others send). BigFix SaaS is the one
exception for numbers: its gateway re-encodes them as JavaScript numbers, so
a floating point can read 3 instead of 3.0 and integers above 2**53 lose
precision (ask for as string when the exact value matters).
String answers are the decoded text on every backend ("a%09b" gives
a<TAB>b). Pass unescape=False to any evaluate* method or to
evaluate_session_relevance() / async_evaluate_session_relevance() (CLI:
--keep-escapes) to get % and control characters as %xx instead
(a%09b), the form Web Reports and qna print, again the same on every
backend. escape_answer() / unescape_answer() convert between the two;
escape_result() does it for a whole result from a backend used directly.
SessionRelevanceClient has the same methods, synchronously, and works even
inside a running event loop. Single backends (RestBackend,
ExplorerBackend, WebReportsBackend, SaasBackend) can be used directly
too.
One long-lived client (GUIs)
A GUI keeps one client for its lifetime: one BigFix SaaS sign-in and one set of discovered deployment ids, whatever each run asks for.
- Prompts may be async.
prompt=(passwords, and BigFix SaaS TOTP codes) may return the answer or an awaitable of it (thePrompttype), as aTrustStorecallback may, so a dialog on the event loop (NiceGUI, Toga, a SwiftUI host through a bridge) is awaited. ReturningNoneor""declines, and nothing is sent: an empty or wrong TOTP code counts toward BigFix SaaS's permanent lock after 100 failed logins. A TOTP code already sent for the account through the same client (orSaasSessionPool) is never sent again either. Password and TOTP prompts are asked one at a time (aTrustStorecallback has its own turn-taking), and each challenge once; a prompt that raises (a cancelled dialog) declines for the run. A declined TOTP challenge is asked again on the next run; one a code was sent for and refused (mfa_mismatch) is not, until the client is rebuilt. A shortread_timeoutnever shortens a BigFix SaaS sign-in or refresh.SessionRelevanceClientcalls prompts on its own loop thread, so a sync caller should pass sync ones. - Per-call read timeout.
evaluate*(..., read_timeout=seconds)replaces every connection's configured read timeout for that call only. It bounds each request the query makes, but neither deployment discovery nor a BigFix SaaS sign-in or refresh, which keep at least the configured one.config.with_timeouts(connect=..., read=...)returns a copy of aConfigwith every connection's timeouts replaced (the CLI's--connect-timeout/--timeout). - Config problems are results. A connection whose settings fail only
when its backend is built (a server with a path, as
BES_ROOT_SERVERcan give) comes back as its own result,error.kind == "config", every run, and the other connections still run. It is never asked for a password. Mistakes in the client's own arguments (an unknownconnections=name or backend) still raiseConfigError. - Display helpers.
result.hostis the server's host name (https://bf.example.com:52311→bf.example.com, orNone), andresult.evaluation_time_textthe evaluation time as the console shows it (0.049ms,4ms, never scientific notation). Neither is into_dict().
from bigfix_remote_session_relevance import AsyncSessionRelevanceClient
async def ask_user(question: str) -> str | None:
return await my_dialog(question, secret=True) # None if cancelled
client = AsyncSessionRelevanceClient(prompt=ask_user)
results = await client.evaluate("number of bes computers", read_timeout=10)
for r in results:
print(r.host, r.evaluation_time_text, r.error.kind if r.error else r.answers)
await abackend_from_config(conn, prompt=...) builds a single backend with
an async prompt (backend_from_config asks for a missing password
synchronously, and refuses an async prompt with TypeError then), and
await conn.aresolve_password(prompt=...) is resolve_password's async
twin. ask(prompt, message) calls either kind of prompt.
The query is always named session_relevance (never a bare relevance, which
could mean client relevance): result.session_relevance, the to_dict() /
--json key, the error kind, and the session_relevance= /
session_relevances= parameters.
Trust on first use
BigFix servers usually present self-signed certificates. With the default
verify = "tofu", a certificate no CA vouches for is decided by the
TrustStore passed as trust=, and a pinned one is from then on the only
certificate that host:port may present. Either way the decision happens in
the TLS handshake, before any request: an unpinned certificate that is
refused, or a pinned host presenting a different one (tls /
pin_mismatch), receives nothing after the handshake: no request, no
Authorization header, no Web Reports password. tests/unit/test_trust.py proves this against a
local TLS server that records every byte.
Choose how a first-use certificate is decided:
from bigfix_remote_session_relevance import AsyncSessionRelevanceClient, TrustStore
TrustStore(callback=ask_user) # ask: a sync or async callback gets a CertInfo
TrustStore(trust_on_first_use=False) # defer: refuse, and record it in store.pending
TrustStore(trust_on_first_use="auto") # auto: pin without asking (logged)
Defer suits front ends that can't show a dialog in the middle of a request (a UI talking to Python over a bridge, or any synchronous caller): run, show what was refused, pin what the user confirms, run again.
store = TrustStore(trust_on_first_use=False)
async with AsyncSessionRelevanceClient(trust=store) as client:
results = await client.evaluate("number of bes computers")
for host_port, cert in store.pending.items(): # each came back as tls/untrusted
if user_confirms(host_port, cert.fingerprint): # SHA-256, AB:CD:… form
store.accept(host_port) # pins it; KeyError if it isn't pending
# run again: accepted hosts now connect
A refused certificate comes back as tls / untrusted, whose message
names the host:port and, when the store recorded the certificate, its SHA-256
fingerprint; detail keeps the TLS error and the CLI hint (--trust-cert).
The structured certificate is in store.pending. accept() raises
ValueError, and pins nothing, if the host has meanwhile been pinned to a
different certificate: replacing a pin stays a deliberate step
(--forget-cert / KnownCerts.forget). A callback that declines
records the certificate in pending too. record_refused=False turns
recording off, and with trust_on_first_use=False also skips the bare
handshake that fetches the certificate.
Auto-accept is opt-in from 1.4.0. TrustStore() with no callback, and
so AsyncSessionRelevanceClient() and evaluate_session_relevance() with
the default trust, still pin any first-use certificate, but now emit a
one-time DeprecationWarning asking for one of the choices above. It is
attributed to your line of code, so Python shows it by default in scripts
run directly and under pytest; elsewhere enable it with -W default or
PYTHONWARNINGS=default. In 2.0
the default will refuse and record (defer). trust_on_first_use="auto"
keeps today's behaviour without the warning; True / False keep working.
The CLI asks when interactive, pins automatically ("auto") when not, and
refuses with --no-tofu, as before, and never shows the warning. A refused
certificate's message now names its fingerprint (still followed by the
--trust-cert hint), and --no-tofu fetches the certificate with a bare
handshake to do so. --show-certs,
--trust-cert NAME|HOST:PORT and --forget-cert HOST:PORT manage pins in
.remote_session_known_certs.toml in ~/.bigfix (or $BFRSR_HOME).
BigFix Query (ClientQuery, provisional)
RestBackend can also send client relevance to agents through the root
server's BigFix Query API, and (since 1.3.0) SaasBackend through BigFix
SaaS fast query, for tools such as
bigfix-remote-client-relevance
that want this package's config, credentials and certificate pinning. It is
opt-in and separate: evaluate() is unchanged. Two calls, and polling is
up to the caller, since rows accumulate as agents answer:
import asyncio
from bigfix_remote_session_relevance import (
RestBackend, TrustStore, load_config, supports_client_query,
)
conn = next(c for c in load_config().connections if c.backend == "rest")
store = TrustStore(trust_on_first_use=False) # or a callback, or "auto"
async with RestBackend.from_config(conn, trust=store) as backend:
assert supports_client_query(backend) # RestBackend and SaasBackend
submitted = await backend.submit_client_query("computer name", [<COMPUTER_ID>])
if submitted.ok and submitted.query_id is not None:
results = await backend.client_query_results(submitted.query_id)
for _ in range(30): # about a minute
if results.rows or not results.ok:
break
await asyncio.sleep(2)
results = await backend.client_query_results(submitted.query_id)
for row in results.rows: # one row per value, per computer
print(row.computer_id, row.computer_name, row.is_failure, row.result)
By default agents evaluate it like qna, with no fixlet or site context, so
relevant fixlets of sites fails (InspectorFixletContextError). Since 1.3.0,
submit_client_query(..., use_client_context=True) asks the agent to
evaluate it in its client context instead (<UseClientContext> in the
BESAPI 11.0.7 schema). The default, None, leaves the element out, so
servers that predate it see the same request as before.
Errors are results here too (response.error is a ResultError); only
caller bugs raise (no computer ids, ids that are not integers, or a
use_client_context that is not a bool). Operators
who are not master operators need the Can Submit Queries permission.
Computers outside the operator's scope are accepted without an error but
never answer, so stop polling on your own timeout.
On BigFix SaaS, a query targets one computer. Several ids come back as
an error result (unsupported_feature / multiple_targets) and nothing is
sent, so submit one query per computer. Since 1.5.0,
client_query_max_targets(backend) says so before you send: 1 for
SaasBackend, None (no limit) for RestBackend and for backends without
the attribute, and TypeError for a backend with no ClientQuery API. Ids
must be positive (ValueError otherwise: the service would treat 0 as no
target, which is every device). A submit also shows up in the operator's
console history, and most failed submits are a bare HTTP 500 that never says why,
whether the computer id is unknown to the deployment (REST would accept it
and never answer) or the root server rejects the client relevance.
To build backends from config the way the clients do, use
backend_from_config(conn, trust=...) (it builds any backend, so check
supports_client_query()), and attach every SaasBackend to one
SaasSessionPool (pool.attach(backend), before its first request) so an
account signs in once and a wrong password costs one failed login, not one
per backend.
Setup from another tool (provisional)
run_setup(path=None, *, backends=None) is the interactive --setup
wizard as a function returning its exit code. path=None is the usual
config path; backends=("rest",) probes, and offers to save, only those
backends.
For an "Add BigFix SaaS account" screen, await saas_sign_in(host, email, password) signs in without a prompt and returns a SaasAccount: its
servers (the sid values), or its error (never raised). It sends one
login, or two when the account needs MFA and you pass totp="123456" (or a
prompt callable, sync or async); without a code an MFA account comes back as
error.code == "totp_required", so ask for the code and call again. A
rejected sign-in is returned, never retried: failed logins count toward a
permanent account lock.
It sends the login even when a session is saved for later runs, so a
wrong password never looks right, and saves the new session. (With a
pool= that is already signed in, it reuses that sign-in, as before.)
Saved sessions (see Saved BigFix SaaS sessions)
use the secrets= store an app passes to AsyncSessionRelevanceClient or
backend_from_config, else default_secret_store(), and the file when there
is none. SaasBackend(..., session_store=None) turns them off for one
backend, SaasSessionStore(path, secrets=...) puts them somewhere else, and
forget_saas_session(conn) is --forget-session.
import dataclasses
from bigfix_remote_session_relevance import saas_sign_in
account = await saas_sign_in("login.bigfix.com", email, password)
if account.ok:
connections = [
dataclasses.replace(c, password=password) # or password_env=...
for c in account.connections() # one per server, named like --setup
]
bigfix_remote_session_relevance.__version__ is the installed version.
Upgrading from 0.4 or earlier: 0.5.0 renamed, with no alias,
result.relevance→result.session_relevance(and the--jsonkey), therelevance=/relevances=parameters →session_relevance=/session_relevances=, error kind"relevance"→"session_relevance", andRelevanceError→SessionRelevanceEvaluationError. Helpers follow suit (encode_session_relevance,parse_session_relevance_response, …).
Compatibility
From 1.0.0, releases follow semantic versioning. Removing or changing any of these needs a new major version:
- Library: the names in
bigfix_remote_session_relevance.__all__and the parameters in their signatures, keyword names included, except the provisional names below.transport/transport_factoryare testing hooks typed with httpx's classes and are not covered. - Results: the
SessionRelevanceResultandResultErrorfields, theto_dict()keys and value types, the error kinds (ERROR_KINDS) and the exception classraise_for_error()raises for each. - CLI: flags, the exit codes in the table above, and the
--jsonoutput (to_dict()per result). - Config file:
schema_version = 1and the keys and backend names in remote_session_connections.example.toml, where the file is looked for (--config,$BFRSR_CONFIG,.remote_session_connections.tomlin$BFRSR_HOMEor~/.bigfix) andBFRSR_LOCAL_ROOT_SERVER. The lenient aliases (url,host,user,type,wr, …) keep working, but may be deprecated, with a warning for at least one minor release first.
Provisional: Backend, RestBackend, ExplorerBackend,
WebReportsBackend, SaasBackend, TrustStore, KnownCerts and
CertInfo, (since 1.1.0) the BigFix Query names ClientQueryExtras,
ClientQueryResponse, ClientQueryRow, supports_client_query and
run_setup, (since 1.4.0) TrustPolicy and ServerAddress, (since
1.5.0) SaasSessionPool, backend_from_config and
client_query_max_targets, (since 1.6.0) saas_sign_in and
SaasAccount, and (since 1.7.0) the password store names SecretStore,
MemorySecretStore, KeyringSecretStore, KeychainSecretStore,
default_secret_store and secret_account, and (since 1.8.0) the saved
SaaS session names SaasSessionStore, SavedSaasSession,
default_saas_sessions_path and forget_saas_session, and (since 1.9.0)
the prompt names Prompt, ask and abackend_from_config, are public and usable, but may change in a minor release
(noted in its release notes). Use the clients for a stable interface.
Additions (a new result field or to_dict() key, error kind or code, flag
or config key) come in minor releases. Code that switches on error kinds
or codes should allow ones it doesn't know. ResultError itself accepts
only the kinds of the installed version, so check kind before rebuilding
one from a newer version's --json. Older versions warn about, and ignore,
config keys they don't know.
Not covered: the plain-text CLI layout and summary, stderr and log messages,
error message wording, detail and raw (the server's own text), the
certificate pin and cache files' formats, and anything not in
__all__ (types such as Pin or ServerAddress that provisional classes
return or take are provisional with them).
Development
uv sync
uv run pytest # offline; live tests skip
BFRSR_LIVE_TESTS=1 uv run pytest tests/integration -n0 # against your config
uv run python scripts/capture_fixtures.py # refresh redacted fixtures
See DESIGN.md for the specification and AGENTS.md for contributor notes.
Metadata
Release files for bigfix-remote-session-relevance 1.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| bigfix_remote_session_relevance-1.9.0.tar.gz | 361.3 kB | Without provenance | Details for bigfix_remote_session_relevance-1.9.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bigfix_remote_session_relevance-1.9.0-py3-none-any.whl | Python 3 | none | any | Details for bigfix_remote_session_relevance-1.9.0-py3-none-any.whl |
Total release size: 491.4 kB
Release files / bigfix_remote_session_relevance-1.9.0.tar.gz
| Download URL | bigfix_remote_session_relevance-1.9.0.tar.gz |
|---|---|
| Size | 361.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a6c2b8baa7b389e8cae281d80db0ecd76b3f459d17ab3d4b534ee389cfeceb07
|
|
BLAKE2b-256 checksum How to use checksums |
afbe7f330f348d9fbb3de729a794f7e70c77d8848720daeafdc07f6409ea17de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / bigfix_remote_session_relevance-1.9.0-py3-none-any.whl
| Download URL | bigfix_remote_session_relevance-1.9.0-py3-none-any.whl |
|---|---|
| Size | 130.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aced14e5e74dd48fc93cf6107eb037c5ec783e9b47678e74c55685e0a974368e
|
|
BLAKE2b-256 checksum How to use checksums |
0e8b50ffa6cdb66beb0600234743c6ad7003ccf31bcf5b945a5227c978c18cc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for bigfix-remote-session-relevance 1.9.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.