Metadata-Version: 2.4
Name: bidda-shield
Version: 0.11.0
Summary: Bidda Compliance Intelligence SDK + `bidda` CLI: full MCP parity (25 tools incl. governed runs with one-call consult that fetches a node and records a verified run entry, signed run receipts + governance audit packs, OSCAL assessment-results export, control attestations, coverage gap check, obligation-delta feed, drift-check, signed attestations, point-in-time, change alerts, jurisdiction compare, topics), api_key + Skyfire + USDC auth, LangChain/AutoGen/CrewAI wrappers
Home-page: https://bidda.com
Author: Bidda Intelligence
Author-email: api@bidda.com
Project-URL: Homepage, https://bidda.com
Project-URL: Documentation, https://bidda.com/developers
Project-URL: Source, https://bidda.com/developers
Project-URL: Registry, https://bidda.com/intelligence
Project-URL: MCP Server, https://bidda.com/mcp
Keywords: compliance,GDPR,EU AI Act,LangChain,AutoGen,CrewAI,regulatory,legal,AI safety
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Office/Business :: Financial :: Accounting
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24.0
Provides-Extra: langchain
Requires-Dist: langchain>=0.1.0; extra == "langchain"
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
Requires-Dist: pydantic>=2.0; extra == "langchain"
Provides-Extra: autogen
Requires-Dist: pyautogen>=0.2.0; extra == "autogen"
Provides-Extra: crewai
Requires-Dist: crewai>=0.28.0; extra == "crewai"
Requires-Dist: crewai-tools>=0.1.0; extra == "crewai"
Provides-Extra: all
Requires-Dist: langchain>=0.1.0; extra == "all"
Requires-Dist: langchain-core>=0.1.0; extra == "all"
Requires-Dist: pydantic>=2.0; extra == "all"
Requires-Dist: pyautogen>=0.2.0; extra == "all"
Requires-Dist: crewai>=0.28.0; extra == "all"
Requires-Dist: crewai-tools>=0.1.0; extra == "all"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# bidda-shield

[![smithery badge](https://smithery.ai/badge/bidda-ai/bidda-compliance)](https://smithery.ai/servers/bidda-ai/bidda-compliance)
[![CISA Secure by Design](https://img.shields.io/badge/CISA-Secure%20by%20Design%20Pledge-blue)](https://bidda.com/cisa/secure-by-design)

**Verified compliance intelligence for AI agents.** Stop your LangChain, AutoGen, and CrewAI agents from hallucinating legal requirements.

```bash
pip install bidda-shield
```

---

## The problem

AI agents making decisions about hiring, credit scoring, data processing, or content moderation are operating under dozens of overlapping regulations â€” GDPR, EU AI Act, HIPAA, CCPA, Basel III. When an agent gets the legal logic wrong, it isn't just a bug. It's a regulatory liability event.

LLMs hallucinate regulations. bidda-shield is built to reduce that risk by giving the model a source-verified answer to ground on instead of its own recall.

Every compliance node in the Bidda registry traces to a specific clause of a primary legal instrument, verified against the source URL, and drift-checked weekly. Nodes are built by Bidda's own deterministic pipeline: internal parsers and multi-gate verification scripts do the heavy lifting, and any AI assistance is confined to a small, tightly-gated drafting step that every node must clear across several independent checks before it ships. The whole design exists to keep drift to a minimum. No inference. No approximation.

---

## Pick your path

| You are... | Use | How to auth |
|---|---|---|
| A developer wanting the simplest start | **API key** (Starter / Pro / Enterprise / evaluation) | `BiddaShield(api_key="...")` |
| Building an autonomous agent with a wallet | **Skyfire JWT** | `BiddaShield(skyfire_token="...")` |
| Headless, no account, on-chain only | **Direct Base USDC** | `BiddaShield(base_tx_hash="0x...")` |
| Just browsing | **No auth** (discovery tier is free) | `BiddaShield()` |

Get an API key at **[bidda.com/pricing](https://bidda.com/pricing)** â€” Starter is $49/mo with 100 unlocks. No key? Discovery is free forever.

---

## 5-minute quickstart

```bash
pip install bidda-shield
```

```python
from bidda_shield import BiddaShield

shield = BiddaShield(api_key="your-bidda-api-key")

# 1. Search the registry (free, no quota hit)
hits = shield.search_nodes("biometric data EU")
print(hits[0]["title"])     # EU AI Act Article 5 â€” Prohibited AI Practices
print(hits[0]["bluf"])      # Plain-English summary

# 2. Pre-flight compliance check (free, the headline tool)
verdict = shield.check_action_compliance(
    "process EU resident biometric data for access control",
    jurisdiction="eu",
)
print(verdict["risk_level"])   # "HIGH"
print(verdict["match_count"])  # 10

# 3. Unlock the full machine-executable workflow for the top match ($0.01)
top = verdict["matches"][0]
node = shield.get_node(top["node_id"], vault=True)
for step in node["deterministic_workflow"]:
    print(step["step"], step["action"])
```

That's it. The pattern: **search â†’ check â†’ unlock**. Free everywhere except the final unlock.

---

## LangChain

```python
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
from bidda_shield import BiddaLangChainTool

llm  = ChatOpenAI(model="gpt-4o")
tool = BiddaLangChainTool()

agent = initialize_agent(
    tools=[tool],
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
)

agent.run(
    "My agent is about to make an automated credit decision. "
    "What regulations apply and what do they require?"
)
```

The tool returns the regulation title, domain, plain-English summary (BLUF), and a link to the full verified node â€” for $0.01 USDC per full unlock.

---

## AutoGen

```python
import autogen
from bidda_shield import BiddaAutoGenTool

config_list = [{"model": "gpt-4o", "api_key": "YOUR_OPENAI_KEY"}]

bidda_tool = BiddaAutoGenTool()

assistant = autogen.AssistantAgent(
    name="compliance_assistant",
    llm_config={
        "config_list": config_list,
        "functions": [bidda_tool.function_schema],
    },
)

user_proxy = autogen.UserProxyAgent(
    name="user",
    human_input_mode="NEVER",
    function_map={"bidda_compliance_lookup": bidda_tool.execute},
)

user_proxy.initiate_chat(
    assistant,
    message="What does GDPR Article 22 require for automated decision-making?",
)
```

---

## CrewAI

```python
from crewai import Agent, Task, Crew
from bidda_shield import BiddaCrewAITool

compliance_tool = BiddaCrewAITool()

compliance_officer = Agent(
    role="Chief Compliance Officer",
    goal="Ensure all AI agent actions comply with applicable regulations",
    backstory="Expert in GDPR, EU AI Act, HIPAA, and global data protection law.",
    tools=[compliance_tool],
    verbose=True,
)

task = Task(
    description="Review the agent action 'train a model on employee performance data' and identify all applicable regulations.",
    agent=compliance_officer,
)

crew = Crew(agents=[compliance_officer], tasks=[task])
crew.kickoff()
```

---

## Direct API usage

```python
from bidda_shield import BiddaShield

shield = BiddaShield()

# Search by keyword
nodes = shield.search_nodes("automated decision making")
for n in nodes:
    print(n["node_id"], "â€”", n["title"])

# Get a specific node (free discovery tier)
node = shield.get_node("gdpr-article-22-automated-decisions")
print(node["bluf"])

# Get full vault data (requires Skyfire JWT or USDC payment â€” $0.01)
shield_paid = BiddaShield(skyfire_token="YOUR_SKYFIRE_JWT")
full_node = shield_paid.get_node("gdpr-article-22-automated-decisions", vault=True)
print(full_node["deterministic_workflow"])  # Step-by-step legal compliance logic
```

---

## Full method reference (v0.10.1 - full 25-tool MCP parity)

Every tool exposed by the `bidda.com/mcp` MCP server is available as a Python
method. Results match what an MCP client would see for the same input â€” the
SDK mirrors the same logic, just returning structured `dict` / `list` data
instead of LLM-formatted markdown.

```python
from bidda_shield import BiddaShield
shield = BiddaShield()

# 1. Browse the registry
shield.list_pillars()                              # â†’ ["AI Governance & Law", ...]
shield.search_nodes("biometric", pillar="ai-gov")  # â†’ [{"node_id", "title", ...}, ...]
shield.get_node("gdpr-article-22-automated-decisions")  # discovery (free)
shield.get_node("gdpr-article-22-automated-decisions", vault=True)  # full ($0.01)

# 2. Walk prerequisites â€” what does this rule depend on?
shield.get_dependency_chain("eu-ai-act-article-10-data-governance-training", max_depth=2)
# â†’ {"root": "...", "title": "...", "chain": [{"depth": 0, ...}, ...], "total": 8}

# 3. Cross-framework mappings â€” GDPR Art 17 â†’ CCPA right-to-delete â†’ POPIA Sec 24
shield.get_crosswalk("gdpr-article-17-right-to-erasure")
# â†’ {"node_id", "title", "dimensions": ["ccpa_equivalent", ...], "vault_url"}

# 4. Regulatory change feed â€” what moved recently
shield.get_latest_changes(days=30, pillar="Cybersecurity")
# â†’ [{"node_id", "title", "domain", "last_updated"}, ...]  (newest first, max 20)

# 5. Jurisdiction-wide rule bundle â€” everything that applies in a market
shield.get_jurisdiction_bundle("eu", limit=25)
# â†’ {"jurisdiction", "total_matches", "by_pillar": {...}, "nodes": [...]}

# 6. MITRE technique â†’ compliance mapping
shield.get_mitre_mapping("T1566")           # ATT&CK Enterprise (phishing)
shield.get_mitre_mapping("AML.T0020")       # ATLAS (AI-specific)
shield.get_mitre_mapping("D3-FIM")          # D3FEND defensive
shield.get_mitre_mapping("CAPEC-66")        # CAPEC attack pattern
# â†’ [{"node_id", "title", "bluf", "dependencies", "crosswalk_dimensions", "vault_url"}, ...]

# 7. Pre-flight compliance check â€” primary agent runtime tool
result = shield.check_action_compliance(
    "process EU resident biometric data for access control",
    jurisdiction="eu",
    limit=10,
)
# â†’ {
#     "action": "...",
#     "keywords": ["process", "biometric", "data", "access", "control"],
#     "risk_level": "HIGH",          # NONE | LOW | MODERATE | HIGH
#     "risk_basis": "relevance of the strongest registry match ...",
#     "top_score": 26.2,             # BM25 relevance of the best match
#     "ranking": "bm25",
#     "match_count": 10,             # size of this page
#     "total_matches": 143,          # everything above the relevance floor
#     "matches": [
#       {"node_id", "title", "domain", "bluf", "matched_terms": [...], "score": 26.2},
#       ...
#     ]
#   }

if result["risk_level"] == "HIGH":
    # Halt the agent action, surface the matched regulations to a human.
    raise RuntimeError(f"Compliance gate failed: {result['match_count']} matches")
```

`risk_level` says how strongly the registry matches the text you submitted. It
is not an assessment of legal risk and it does not decide whether an action is
permitted. Gate on it if you want a cheap tripwire, then have a person read the
matched obligations.

### Subscriber tools (pass `api_key=` â€” a free trial counts)

```python
# 8. Browse the registry by cross-cutting compliance topic (free, no key)
shield.browse_topics("data breach notification")
# â†’ [{"node_id", "title", "pillar", "jurisdiction"}, ...] across every pillar

# 9. Compare how jurisdictions address one topic, including where numeric
#    thresholds differ (e.g. 72 hours vs 30 days). Does not rank strictness.
shield.compare_jurisdictions("data breach notification", api_key="YOUR_BIDDA_KEY")

# 10. Signed, time-stamped record of which rules a person or agent relied on
shield.create_attestation(
    agent="loan-bot-v2",
    nodes=["gdpr-article-22-automated-decisions"],
    api_key="YOUR_BIDDA_KEY",
)
# â†’ {"id", "signature", "verify_url", "created_at"}

# 11. Signed record of which committed version was authoritative at a past date
shield.point_in_time("gdpr-article-22-automated-decisions", at="2026-01-15", api_key="YOUR_BIDDA_KEY")

# 12. Subscribe to email/webhook alerts when a watched rule's source changes
shield.watch_changes(node_id="eu-ai-act-article-13-transparency", email="you@org.com", api_key="YOUR_BIDDA_KEY")
```

### Run ledger â€” a signed log of a whole task or conversation

A single attestation covers one decision. A *run* covers a whole task or
conversation (for example a support-bot chat). Open a run, record one entry per
turn as the agent consults rules and answers, then seal it into one signed
**run receipt** that covers every turn. The end user's input can be stored as
text, or privately as a hash that never leaves your process.

```python
# Easiest: a context manager that opens on enter and seals on exit.
with shield.run(agent="acme-support-bot", label="chat 8f21") as run:
    run.record(
        user_input="Can you delete all my data?",
        nodes=["eu-gdpr-article-17-right-to-erasure"],
        decision="explained erasure right + 30-day window",
    )
    run.record(
        user_input="And confirm in writing?",
        hash_only=True,                 # stores only a sha256 of the message
        decision="confirmed email follow-up",
    )
receipt = run.receipt                   # signed; covers both turns
print(receipt["receipt_id"], receipt["verify_url"])

# Or call the four methods directly:
# 13. open_run        -> {"run_id", ...}
# 14. record_run_entry(run_id, nodes=, decision=, note=, input_hash=, ...)
# 15. seal_run(run_id) -> signed run receipt with a public verify_url
# 16. get_run(run_id)  -> the run + entries (a sealed run reports signature_valid)
opened = shield.open_run(agent="acme-support-bot", label="chat 8f21", api_key="YOUR_BIDDA_KEY")
shield.record_run_entry(opened["run_id"], nodes=["eu-gdpr-article-17-right-to-erasure"],
                        note="User: delete my data", decision="explained", api_key="YOUR_BIDDA_KEY")
sealed = shield.seal_run(opened["run_id"], api_key="YOUR_BIDDA_KEY")
```

Anyone you hand the receipt to can verify it against Bidda's public key with no
Bidda account. Opening, recording and sealing need an active subscription (a
free trial counts); verifying a sealed receipt is free.

### Governed runs - consult a rule and record the proof in one call

```python
with shield.run(agent="loan-bot-v2", label="application 4411") as run:
    # 17. Run.consult: fetch the full node AND record a verified, hash-pinned
    #     run entry in one step. The sealed receipt then proves exactly which
    #     version of the rule the agent read.
    node = run.consult(
        "eu-gdpr-article-22-automated-decisions",
        decision="routed to human review",
        model="gpt-5.2",          # optional: which model decided
        subject="user-8812",      # optional: stored only as a private hash
    )
# 18. audit_pack: one auditor-ready evidence pack for a sealed run - the signed
#     receipt, the entry chain, and an independent integrity self-check.
pack = shield.audit_pack(run.receipt["run_id"])   # also available as run.audit_pack()
```

### Governance tools

```python
# 19. drift_check: is the law this agent cached still current? Pass the
#     anchors you stored when you grounded ({"node_id", "hash"}); each comes
#     back fresh, drifted, or withdrawn.
shield.drift_check([{"node_id": "eu-ai-act-article-10-data-governance-training",
                     "hash": "sha256:..."}])

# 20. create_control_attestation: sign a record mapping one of YOUR controls
#     to the obligations it addresses. An audit trail, not a determination.
shield.create_control_attestation(
    control="Access review",
    statement="Quarterly review of privileged access.",
    nodes=["iso-27001-annex-a-access-control"],
    framework="ISO 27001", control_owner="Jane Smith", control_status="operating",
)

# 21. gap_check: walk the dependency graph from the rules you cover and
#     surface prerequisite obligations you did not list.
shield.gap_check(["eu-ai-act-article-10-data-governance-training"], depth=2)

# 22. obligation_deltas: which obligations changed at the source since a date.
shield.obligation_deltas(since="2026-06-01", pillar="AI Governance & Law")

# 23. oscal_assessment_results: export a sealed run as a NIST OSCAL
#     assessment-results document for GRC tooling.
shield.oscal_assessment_results(sealed["run_id"])
```

The discovery index is cached client-side for 5 minutes after the first
call, so chained calls (e.g. `check_action_compliance` followed by
`get_dependency_chain` on the top match) reuse the same fetch.

---

## What's in a full node

Each vault-tier node contains:

- **BLUF** â€” plain-English summary of the legal obligation
- **deterministic_workflow** â€” step-by-step compliance checklist derived from the primary legal text
- **actionable_schema** â€” machine-readable compliance checkpoints
- **primary_citations** â€” exact section references to the legal instrument
- **crosswalks** â€” mappings to NIST, ISO, and peer standards
- **dependencies** â€” other regulations this one depends on or triggers
- **verification** â€” source URL, jurisdiction, instrument type, integrity hash

All content traces to a real primary legal source. No secondary commentary. No paraphrasing.

---

## Authentication

The vault tier (full 13-key node + workflow + citations) costs $0.01 per node. Three ways to pay:

```python
import os
from bidda_shield import BiddaShield

# 1. Subscription / evaluation key â€” easiest, recommended for most devs
shield = BiddaShield(api_key=os.getenv("BIDDA_API_KEY"))

# 2. Skyfire JWT â€” agent-native, autonomous payments
shield = BiddaShield(skyfire_token=os.getenv("BIDDA_SKYFIRE_TOKEN"))

# 3. Direct Base USDC â€” headless, no account needed
shield = BiddaShield(base_tx_hash="0xYOUR_TRANSACTION_HASH")
```

Pick **one** path per client. Discovery tier (search, BLUF, MCP tools) works
with no auth at all and is free forever.

---

## Install options

```bash
# Core (no framework dependencies)
pip install bidda-shield

# With LangChain
pip install "bidda-shield[langchain]"

# With AutoGen
pip install "bidda-shield[autogen]"

# With CrewAI
pip install "bidda-shield[crewai]"

# Everything
pip install "bidda-shield[all]"
```

---

## Registry coverage

- **10,099 verified nodes** across 39 sovereign pillars
- **Pillars:** AI Governance, Cybersecurity, Banking & Finance, Healthcare, Legal & IP, ESG, Workplace, Aviation & Defense, Crypto, Cloud, and 29 more, plus a MITRE layer (ATT&CK Enterprise/Mobile/ICS, D3FEND, ATLAS, CAPEC)
- **Jurisdictions:** EU, US, UK, Germany, Australia, Singapore, South Africa, India, Brazil, Japan, Canada, China, Hong Kong, and global instruments
- **Sources:** EU AI Act, GDPR, NIST CSF, ISO 27001, Basel III/IV, HIPAA, DORA, NIS2, FATF, MITRE ATT&CK/ATLAS/D3FEND/CAPEC, and 150+ authority bodies

Full registry: [bidda.com/intelligence](https://bidda.com/intelligence)

---

## CISA Secure by Design

Bidda is a public signatory of the [CISA Secure by Design Pledge](https://bidda.com/cisa/secure-by-design) and publishes a [CISA Cybersecurity Performance Goals crosswalk](https://bidda.com/cisa/cpg-crosswalk) mapping its registry to CISA's CPGs. CISA capabilities Bidda offers federal, SLTT and critical-infrastructure defenders at no cost are catalogued at [bidda.com/cisa/free](https://bidda.com/cisa/free).

---

## Links

- Registry: [bidda.com](https://bidda.com)
- API docs: [bidda.com/developers](https://bidda.com/developers)
- MCP server: `https://bidda.com/mcp` (Claude.ai, Claude Desktop, any MCP client)
- CISA programs: [bidda.com/cisa](https://bidda.com/cisa)
- Package: [pypi.org/project/bidda-shield](https://pypi.org/project/bidda-shield)
- Support: [api@bidda.com](mailto:api@bidda.com)

---

## License

MIT â€” use freely, attribution appreciated.
