Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
be100ef
Update verdict version
xlloit Sep 20, 2026
f953111
Add a verified GMP source archive
xlloit Sep 23, 2026
8453ca5
Build Docker images from the pinned GMP archive
xlloit Sep 23, 2026
609b7a7
Carry key tweaks through signing and verification
xlloit Sep 23, 2026
3b057cd
Describe authority artifacts with JSON schemas
xlloit Sep 23, 2026
055fd8b
Register payment policy functions
xlloit Sep 23, 2026
e4855f4
Return composed signing results through the API and SDK
xlloit Sep 23, 2026
89504e1
Add transaction requests and results to the Java SDK
xlloit Sep 23, 2026
05843cd
Add payment requests and credentials to the Java SDK
xlloit Sep 23, 2026
6f2a58d
Move Bitcoin transaction parsing into digital assets
xlloit Sep 23, 2026
a724f66
Check Bitcoin scripts against the signing key
xlloit Sep 23, 2026
f592884
Move EVM transaction validation into digital assets
xlloit Sep 23, 2026
674a857
Compose signed EVM transactions
xlloit Sep 23, 2026
ae7eb45
Validate Tron transactions and signing keys
xlloit Sep 23, 2026
7ee79dd
Compose signed Tron transactions
xlloit Sep 23, 2026
71eeb83
Validate XRP transactions and signing keys
xlloit Sep 23, 2026
152a892
Compose signed XRP transactions
xlloit Sep 23, 2026
9c1891a
Validate Solana transactions and signing keys
xlloit Sep 23, 2026
a7202f2
Compose signed Solana transactions
xlloit Sep 23, 2026
8b0f973
Validate payment mandates and disclosures
xlloit Sep 23, 2026
b453390
Validate checkout signatures and credential claims
xlloit Sep 23, 2026
77ab288
Materialize payment commands and compose credentials
xlloit Sep 23, 2026
7fc5d05
Sign AP2 mandates
xlloit Sep 23, 2026
fc17c58
Sign Mastercard Verifiable Intent mandates
xlloit Sep 23, 2026
af4982f
Handle MCP requests over HTTP
xlloit Sep 23, 2026
8598f81
List identities and authorities through MCP
xlloit Sep 23, 2026
2745578
Expose signing and composition as MCP tools
xlloit Sep 23, 2026
532fee4
Expose status, public keys and verification as MCP tools
xlloit Sep 23, 2026
e0daad6
Add digital asset Gradle projects
xlloit Sep 23, 2026
ddd0a7a
Add payment and MCP Gradle projects
xlloit Sep 23, 2026
6599d22
Enable the new features in the root build
xlloit Sep 23, 2026
4e1322a
Prepare Keeper nodes for new integration scenarios
xlloit Sep 23, 2026
978e9b5
Publish payment and digital asset authority fixtures
xlloit Sep 23, 2026
c2a71d8
Test digital asset signing and composition
xlloit Sep 23, 2026
9ad624f
Test agentic payment credentials
xlloit Sep 23, 2026
feeaf44
Test MCP discovery, permissions and actions
xlloit Sep 23, 2026
1ec8e04
Document governed AI actions and agentic payments
xlloit Sep 23, 2026
57e7418
Document digital asset signing
xlloit Sep 23, 2026
61666f7
Document PKI certificate signing
xlloit Sep 23, 2026
88647b6
Document typed administrative actions
xlloit Sep 23, 2026
2186df6
Explain Composer results and the SDK API
xlloit Sep 23, 2026
282bb04
Explain AP2 and MC VI authorities
xlloit Sep 23, 2026
de8def8
Add a digital asset authority index
xlloit Sep 23, 2026
54fdfa2
Move the Bitcoin authority guide into digital assets
xlloit Sep 23, 2026
1281ec0
Move the EVM authority guide into digital assets
xlloit Sep 23, 2026
53337c7
Document Tron transaction signing
xlloit Sep 23, 2026
7123e9b
Document XRP transaction signing
xlloit Sep 23, 2026
88ccb72
Document Solana transaction signing
xlloit Sep 23, 2026
47d5303
Update the use case navigation
xlloit Sep 23, 2026
e916eb4
Document the new feature modules
xlloit Sep 23, 2026
1855db6
Update build, platform and SDK guides
xlloit Sep 23, 2026
9d0f8e0
Update authority and transaction references
xlloit Sep 23, 2026
ab78afe
Explain MCP connection and available tools
xlloit Sep 23, 2026
815a7ab
Correct recovery authentication example
xlloit Sep 23, 2026
61d8bf4
Bump version to 2.5.0
xlloit Sep 23, 2026
18589c5
Document AP2 authorities with a complete example
xlloit Sep 23, 2026
5ceb3de
Document MC Intent authorities with a complete example
xlloit Sep 23, 2026
85e3c69
Move agentic payment guidance into its own directory
xlloit Sep 23, 2026
c385448
Link payment guides from authority documentation
xlloit Sep 23, 2026
c9a08e8
Link payment examples from AI, SDK and module guides
xlloit Sep 23, 2026
09e4fba
Reorganize docs
xlloit Sep 23, 2026
335921a
Update README
xlloit Sep 23, 2026
0c6f43f
Update examples
xlloit Sep 24, 2026
39a5fc4
Align dependencies and add platform-specific builds
xlloit Sep 24, 2026
972fb39
Align module plugin and crypto versions
xlloit Sep 24, 2026
1afe0e7
Align SDK dependencies and test fixtures
xlloit Sep 24, 2026
9b2860e
Verify native libraries and configure Docker JVMs
xlloit Sep 24, 2026
df2314a
Update build and API documentation
xlloit Sep 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ RUN dnf install -y \
m4 \
make \
pkgconf-pkg-config \
wget \
xz \
&& dnf clean all

Expand Down Expand Up @@ -38,8 +37,10 @@ RUN git clone https://github.com/bitcoin-core/secp256k1.git \
&& make -j"$(nproc)" \
&& make install

RUN wget -O gmp.tar.xz https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz \
&& tar -xf gmp.tar.xz \
COPY vendor/gmp/gmp-6.3.0.tar.xz vendor/gmp/SHA256SUMS ./

RUN sha256sum --check --strict SHA256SUMS \
&& tar -xf gmp-6.3.0.tar.xz \
&& cd gmp-6.3.0 \
&& ./configure --enable-shared --disable-static --enable-fat \
&& make -j"$(nproc)" \
Expand All @@ -49,6 +50,8 @@ FROM registry.access.redhat.com/ubi9/openjdk-25:1.24

ARG TKEEPER_VERSION=dev
ARG TKEEPER_JAR=build/docker/tkeeper.jar
ARG TKEEPER_TARGET=all
ARG TKEEPER_ECC=true

LABEL maintainer="TKeeper Labs" \
app.name="tkeeper" \
Expand All @@ -63,13 +66,16 @@ ENV JAVA_OPTS_APPEND="\
-Dcom.sun.management.jmxremote=false \
-Djdk.serialFilter=!* \
-Djdk.tls.client.protocols=TLSv1.3,TLSv1.2 \
-Djava.library.path=/usr/local/lib:/usr/lib64:/lib64:/usr/lib:/lib \
-Dmsgpack.universal-buffer=true \
-XX:+UseCompactObjectHeaders \
--enable-native-access=ALL-UNNAMED"

COPY --from=native-build /usr/local/lib/libgmp.so* /usr/local/lib/
COPY --from=native-build /usr/local/lib/libsecp256k1.so* /usr/local/lib/
COPY --from=native-build /usr/local/lib/libsodium.so* /usr/local/lib/
COPY --chown=185:0 ${TKEEPER_JAR} /deployments/tkeeper.jar
COPY --chown=185:0 tools/NativeJarSmoke.java /tmp/NativeJarSmoke.java

RUN printf '%s\n' \
'public class NativeSmoke {' \
Expand All @@ -83,7 +89,12 @@ RUN printf '%s\n' \
&& java \
-Djava.library.path=/usr/local/lib \
/tmp/NativeSmoke.java \
&& rm /tmp/NativeSmoke.java
&& java \
--enable-native-access=ALL-UNNAMED \
-Djava.library.path=/usr/local/lib:/usr/lib64:/lib64:/usr/lib:/lib \
-cp /deployments/tkeeper.jar \
/tmp/NativeJarSmoke.java "${TKEEPER_TARGET}" "${TKEEPER_ECC}" \
&& rm /tmp/NativeSmoke.java /tmp/NativeJarSmoke.java

ENV JAVA_APP_JAR="/deployments/tkeeper.jar"

Expand Down
236 changes: 33 additions & 203 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,232 +1,62 @@
![TKeeper logo](assets/tk-bg.png)

<div align="center">

# TKeeper

[TKeeper Labs](https://tkeeper.org) • [exploit.org](https://exploit.org) • [Documentation](docs/README.md) • [OpenAPI](openapi.yaml)

</div>

TKeeper is a governed cryptographic identity layer for machines, agents, services, and workflows.

A TKeeper identity combines:

- cryptographic key material, held locally or split across peers
- an authority manifest that defines which typed actions the identity can authorize
- controls for callers, policy, approvals, quorum, lifecycle, and audit

While traditional access control decides whether a caller may reach an API, TKeeper also decides whether the selected identity may authorize the exact requested action.

For typed authorities, the enforcement contract is simple: \
**If TKeeper can't understand and approve the action, it won't produce signature.**

## How it works

```text
Machine / Agent TKeeper Backend
─────────────── ─────── ───────

Requests an action ────> Understands the exact intent
Enforces authority and policy
Collects approval / quorum
Produces signature ────> Verifies the signature
Executes the action
```

TKeeper produces a signature/transaction/certificate only after the request passes the identity's controls. The downstream system must enforce signature validation before executing the effect.

## Use cases

For each use case you can build TKeeper which its own feature modules.

| Use case | What the identity governs |
|------------------|---------------------------------------------------------------|
| AI agents | typed tool and production actions, spending, signed decisions |
| Crypto assets | exact EVM and Bitcoin transactions, treasury workflows |
| Certificates | X.509 issuance and workload identity operations |
| Internal systems | typed commands, privileged automation, break-glass flows |

See [Use Cases](docs/use-cases/README.md).

### Quick example

An AI support agent can refund small orders automatically. Larger refunds require human approval.

```yaml
id: refund-order
type: custom

config:
fields:
orderId: { type: string }
amount: { type: bigint }
expiresAt: { type: time }

policy:
fallback: DENY

approvers:
support-lead:
algorithm: ED25519
publicKey64: "..."

allow:
- id: automatic-refund
where:
- "bigint.lte(amount, '100')"
- "!time.after(time.now(), expiresAt)"

- id: reviewed-refund
where:
- "bigint.gt(amount, '100')"
- "bigint.lte(amount, '1000')"
- "!time.after(time.now(), expiresAt)"
approvals:
threshold: 1
approvers: [support-lead]
```

Now when AI agent asks TKeeper to sign a refund request
- If refund amount is less or equal `100`, it will approve request and produce signature, that backend must verify before execution.
- If refund amount is in `100.1000`, TKeeper will require [human approval](docs/security-model/four-eye-control.md) to produce proof.
- If refund amount is more than `1000`, TKeeper will decline the request.

```json
{
"keyId": "support-agent",
"command": {
"type": "custom",
"authorityId": "refund-order",
"artifact": {
"scheme": "ECDSA",
"hash": "SHA256",
"typed": {
"orderId": "ord_123",
"amount": "<amount>",
"expiresAt": "2030-01-02T03:09:05Z"
}
}
}
}
```

## Authorities

Authorities define what a key identity may authorize.

| Authority type | Use |
|------------------------|---------------------------------------------------------|
| `arbitrary` | raw signing; high-risk, no semantic intent in TKeeper |
| `custom` | typed JSON commands, internal systems, AI-agent actions |
| `evm.transaction` | governed EVM transaction signing |
| `bitcoin.transaction` | governed Bitcoin transaction signing |
| `x509.tbs-certificate` | governed certificate issuance |
[Website](https://tkeeper.org) · [Documentation](docs/README.md) · [OpenAPI](openapi.yaml) · [Java SDK](sdk/README.md)

Concrete authorities use digest-pinned authority documents that act as capability manifests. TKeeper materializes the command into an intent, evaluates policy, and signs only when the final decision is `ALLOW`.
`custom` is available out of the box. Raw `arbitrary` signing is built in but disabled by default;
enable `keeper.authority.arbitrary.enabled` only when raw signing is intentional. Other authority
types can be included during the build.
TKeeper provides cryptographic identities for AI agents, services, and other non-human actors. Each identity combines:

See [Signing and Authorities](docs/signing-and-authorities/README.md).
- a key, held by one node or split across a threshold quorum;
- an authority manifest attached to that key, defining which actions it can authorize;
- controls for callers, policy, approvals, audit, and key lifecycle.

## Deployment modes
As agents move from proposing actions to moving funds and changing production systems, applications need verifiable authorization for each action. TKeeper checks the identity's manifest and controls, then signs the approved action. The receiving system verifies that signature before executing it. Teams use this boundary to build and secure agent tools and payments, digital asset applications, PKI, and internal automation.

TKeeper supports 2 deployment modes, one for low-risk and the other for mid-high risk organizations.
## How an identity authorizes an action

### Mono
TKeeper is deployed as single instance. It is the simplest form designed for small orgs where no high-risk (e.g money transfers) actions are executed.
1. A caller authenticates and requests a signature with a specific key.
2. TKeeper checks the caller's permission and the key's authority. For a typed command, the authority interprets the action and its policy checks it.
3. TKeeper collects required approvals and, in threshold mode, a signing quorum. An allowed command gets a signature.
4. The receiving system verifies the signature or artifact, then executes the authorized action (for example, broadcasting the transaction).

### Threshold
TKeeper is deployed as `t` of `n` quorum, where `n` defines total number of TKeeper nodes, `t` defines **compromise tolerance** and `n-t` defines **fault tolerance**.
`POST /v2/keeper/sign` returns a signature.
`POST /v2/keeper/compose` runs the same checks and can return a signed transaction, payment credential or any other "composed" artifact. [Signing and Authorities](docs/signing-and-authorities/README.md) explains the request and policy model.

Simply talking, if you deployed `2-of-3` configuration, it means that:
Raw `arbitrary` signing has no intent policy and is disabled by default.

- While **2** nodes are not compromised, attacker can't produce fake proof, steal key or tamper policies.
- If **1** node is unavailable (e.g. network error), the system continues to work without interruptions.
## What you can govern

This mode is designed for high-risk organizations, as it allows to distribute risks inside/across organizations, prevents silent policy weakening, and even allows control to be shared externally (for example, between a platform and users of a crypto wallet).
| Work | Guide |
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Agent tools over MCP; AP2 and Mastercard Verifiable Intent payments | [MCP action](docs/use-cases/for-ai.md#govern-an-mcp-action) · [AP2](docs/ai/agentic-payments/ap2.md) · [MC Intent](docs/ai/agentic-payments/mcintent.md) |
| Bitcoin, EVM, Tron, XRP, and Solana transactions | [For Digital Assets](docs/use-cases/for-digital-assets.md) · [Chain authorities](docs/digital-assets/README.md) |
| X.509 certificate signing | [For PKI](docs/use-cases/for-pki.md) · [X.509 example](docs/pki/x509.md#authority-example-workload-server-certificate) |
| Typed commands for internal systems | [For Other Activities](docs/use-cases/for-other-activities.md) · [Custom authorities](docs/signing-and-authorities/arbitrary-and-typed.md) |

>
> TKeeper can be first configured in mono mode and then promoted to `t-of-n` quorum.
>
## Multi-Party Computation and compromise resistance

See [Quorum Modes](docs/security-model/quorum-modes.md).
TKeeper supports `mono` and `threshold` operating modes. In `mono`, one host holds the full key material; compromising that host compromises the identity.

## Documentation
In `threshold` mode, TKeeper uses multi-party computation (MPC) for operations. Each peer holds one key share and checks the operation before contributing. A signature needs `t` accepted contributions from `n` peers. Normal threshold signing does not reconstruct the private key.

- [Product Overview](docs/overview/README.md)
- [Use Cases](docs/use-cases/README.md)
- [Getting Started](docs/getting-started/README.md)
- [Deployment](docs/deployment/README.md)
- [Security Model](docs/security-model/README.md)
- [Status and Limitations](docs/overview/status-and-limitations.md)
- [Cryptographic Identities](docs/key-management/README.md)
- [Signing and Authorities](docs/signing-and-authorities/README.md)
- [Crypto Platforms](docs/crypto-platforms/README.md)
- [API Reference](docs/api-reference/README.md)
- [Operations](docs/operations/README.md)
For a `2-of-3` identity, one compromised peer cannot sign alone or recover the key from its share. One unavailable peer leaves two that can still sign. The protection boundary ends at two compromised peers, and signing stops if fewer than two healthy peers can participate.

## Build
Place peers across separate hosts and failure domains to distribute compromise risk. Honest peers with matching authority and policy state reject actions that violate those rules, even if a minority peer is compromised. Keys created with distributed key generation never exist whole on one peer; imported or promoted keys may have existed whole earlier. See [Quorum Modes](docs/security-model/quorum-modes.md) and the [Threat Model](docs/security-model/threat-model.md).

Cryptographic implementations are selected at build time.
## Get started

| Platform | Provides |
|----------|------------------------------------------------------------------------------|
| `ecc` | `SECP256K1`, `P256`, `ED25519`, ECDSA, FROST, BIP-340/Taproot, ECIES support |
| `pqc` | `MLDSA44`, `MLDSA65`, `MLDSA87`, threshold ML-DSA DKG and signing |
Follow [Local Single Node](docs/getting-started/local-single-node.md) to try TKeeper. A default production build requires Java 25:

A deployable artifact must include at least one platform.

Build all default production features and platforms:

```bash
```sh
./gradlew :build -Pkeeper.features=all -Pkeeper.platforms=all
```

Build only what you need:

```bash
./gradlew :build -Pkeeper.features=authority-evm -Pkeeper.platforms=ecc
```

See [Build and Features](docs/deployment/build-and-features.md).

## Security references

**Security assurance:** 367 automated functional scenarios, including 90
protocol and corruption failure-injection scenarios plus one 3-of-5 share-recovery scenario, run
for every pull request and commit to `main`. See
[Security Assurance](docs/security-model/security-assurance.md) for tested attack
vectors and executable evidence.

- [TKeeper Threat Model](docs/security-model/threat-model.md)
- [Anvil](https://github.com/exploit-org/anvil) for protocol-level cryptographic components

## API

The HTTP contract is described by [openapi.yaml](openapi.yaml).

Java integrations can use [`org.exploit:tkeeper-sdk:2.4.1`](sdk/README.md).

## Verification

Build a selected production artifact and run its root, SDK, feature, and platform unit tests:

```bash
./gradlew build -Pkeeper.features=all -Pkeeper.platforms=all
```

Run the complete release gate:

```bash
./gradlew releaseGate
```
`all` includes default production features. MCP, developer authentication, policy dry run, and recovery require explicit selectors. See [Build and Features](docs/deployment/build-and-features.md) before building a smaller artifact.

`releaseGate` runs every module's unit tests, verifies artifact isolation, builds `exploit/tkeeper:dev` and `exploit/tkeeper:production-it`, and runs the functional integration suite. Performance benchmarks remain separate. Do not deploy either test image as production runtime.
To package native libraries for one OS/CPU instead of all bundled variants, add `-Ptarget=linux-amd64` (or another [supported target](docs/deployment/build-and-features.md#select-a-native-oscpu-target)). The default `-Ptarget=all` keeps all bundled variants.

See [integration-tests](integration-tests/README.md).
Use the [Java SDK](sdk/README.md) or [OpenAPI](openapi.yaml) to integrate. For production boundaries, read the [Threat Model](docs/security-model/threat-model.md) and [Status and Limitations](docs/overview/status-and-limitations.md).

## License
Run the full release checks with `./gradlew releaseGate`. See [Integration Tests](integration-tests/README.md) for the Docker-backed suite.

Apache License 2.0. See [LICENSE.md](LICENSE.md).
2 changes: 1 addition & 1 deletion THREAT_MODEL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TKeeper Threat Model

The maintained threat model lives in [docs/threat-model.md](docs/threat-model.md).
The maintained threat model lives in [docs/security-model/threat-model.md](docs/security-model/threat-model.md).

Protocol-level details for FROST, GG20, ECIES, ZK proofs, nonce handling, Paillier, and curve math live in the tss4j threat model:

Expand Down
Binary file modified assets/tk-bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading