JSON is all you need! **

As a developer, this is a good place to start. For deeper dives, review the code at JACS on github. For misc, watch our tutorials on YouTube

JACS docs are in a format already widely adopted and enjoyed: JSON. However, JACS can sign any type of document that can be checksummed, and any JSON document can be an embedded JACS document. The documents with signatures are always JSON. Therefore, they are independent of network protocols or database formats and can be shared and stand-alone.

You will use JACS lib and an agent to validate a document. To use, you create JSON documents and then sign them with your agent. Maybe this doesn't seem incredibily important at first. When agents start automating and exchanging large amounts of data, quality, consent are only possible with identity. There are good arguments about why identity should be centralized or decentralized. JACS is neutral in that discusssion, except that generating a private key for your agent is a form of decentralization.

JACS is for general documents, but focuses on the idea of Agents, Tasks and Messages, making it easier to create an audit trail of modifications to tasks, agreements, resoutions, etc.

Installation

To install the command line tool for creating and verifying agents and documents

$ cargo install jacs
$ jacs --help

If you are working in Rust, add the rust lib to your project

cargo add jacs

Flexible

Flexible for developers - store, index, and search the docouments how you like.

Any JSON document can be used as a JACS doc as long as it has the JACS header, which are some required fields about the creator and version. Enforcement of schemas relies on JSON Schema's as a basic formalization.

Ease of use

JACS is not meant to be the easiest to use, but it should be useful as is for some specific applicaitons. More importantly it is open source.

If your focus is building an AI business, or selling data to AI, there's quite a lot of work to do. For ease of use and safety of sharing documents (tasks) devs building connected Agent Apps will want to use services provided by https://hai.ai

setting up

First, configure your configuration which are loaded as environment variables. Create a jacs.config.json from the example For an explanation see the schema for the config.

To create a config file, you can run

jacs config create

Which will give you this dialog:

Please enter the data directory path:
Please enter the key directory path:
Please enter the agent private key filename:
Please enter the agent public key filename:
Please enter the agent key algorithm:
Please enter the agent schema version:
Please enter the header schema version:
Please enter the signature schema version:
Please enter the private key password:
Please enter the agent ID and version:

You can use jacs config read to check the configs.

Note: Do not use jacs_private_key_password in production. Instead, use the environment variable JACS_PRIVATE_KEY_PASSWORD in a secure manner. This encrypts a private key needed for signing documents. You can create a new version of your agent with a new key, but this is not ideal.

developing

The pre-commit hook requires some libraries

See pre-commit

  • install jq e.g. brew install jq or use your package manager (e.g., apt install jq for Debian/Ubuntu)
  • for documentation npm install -g @adobe/jsonschema2md
  • cargo install mdbook

Otherwise, it's a standard Rust project.

  • install Rust and your favorite editor
  • see tests, examples, and benches

For a complete guide on setting up a Rust development environment, refer to the official Rust installation guide.

After setting up your environment, you can proceed to the next steps in the documentation to begin working with JACS.

Agents

To use JACS you create an Agent and then use it to create docoments that conform to the JACS Header format.

First, create a json document that follows the schema for an agent, and use it in the library to start building other things.

{
  "$schema": "https://hai.ai/schemas/agent/v1/agent-schema.json",
  "name": "Agent Smith",
  "agentType": "ai",
  "description": "An agent without keys, id or version",
  "favorite-snack": "mango"
}

An id, version etc, will be created when you load the file from the command line

jacs agent create ./examples/raw/mysecondagent.new.json --create-keys true

Your agent will look something like this and you will have also created keys. The agent is self-signed and all the fields are hashed. There is also a public and private key created in the directory set with jacs_key_directory. DO NOT use the keys included in the repo.

{
  "$schema": "https://hai.ai/schemas/agent/v1/agent-schema.json",
  "agentType": "ai",
  "description": "An agent without keys, id or version",
  "jacsId": "809750ec-215d-440f-9e03-f71114924a1d",
  "jacsOriginalDate": "2024-04-11T05:40:15.934777+00:00",
  "jacsOriginalVersion": "8675c919-cb3a-40c8-a716-7f8e04350651",
  "jacsSha256": "45c7af0a701a97907926910df7005a0a69e769380314b1daf15c7186d3c7263f",
  "jacsSignature": {
    "agentID": "809750ec-215d-440f-9e03-f71114924a1d",
    "agentVersion": "8675c919-cb3a-40c8-a716-7f8e04350651",
    "date": "2024-04-11T05:40:15.949350+00:00",
    "fields": [
      "$schema",
      "agentType",
      "description",
      "jacsId",
      "jacsOriginalDate",
      "jacsOriginalVersion",
      "jacsVersion",
      "jacsVersionDate",
      "name"
    ],
    "publicKeyHash": "8878ef8b8eae9420475f692f75bce9b6a0512c4d91e4674ae21330394539c5e6",
    "signature": "LcsuFUqYIVsLfzaDTcXv+HN/ujd+Zv6A1QEiLTSPPHQVRlktmHIX+igd9wgStMVXB0uXH0yZknjJXv/7hQC0J5o5ZuNVN+ITBqG8fg8CEKPAzkQo3zdKfTWBw/GfjyyvItpZzQMGAPoOChS0tc0po5Z8ftOTmsxbfkM4ULGzLrVrhs21i/HpFa8qBzSVyhznwBT4fqOP6b1NZl7IABJS3pQdKbEZ9+Az+O4/Nl55mpfgAppOEbr5XNFIGRKvQ3K5oJS55l6e3GrbH3+5J3bDC1Gxh4wbqYJXVBVKipdJVCtoftEoi1ipTxVtv6j/86egUG7+N1CA6p33q1TXJqwqh4YNFq+9XAAj4X7oSyChA5j4VGegl6x5g+qGMszLGJC2oK6Xalna4dGETe3bjx9+QBQKrYc9T3K3X7Ros0uahiUyx8ekuX25ERGojtYIOpjcGLiPGtp95lbbnX/0cLcbJC2IZjduBeS76RTHlt3/RG5ygbzwK3Pao41wVNJyjLoy5SCi6pguTDjMBGQWjTOfKmK3vv9E8tI6T2lJJqeLtNLIkBpZ2KodqkcTr+80ySehMKglwHBQkjx646afCb+dOwdqhhHQt1gSasQRTxHUWg9NcmZ2uqJoXgQ/mGhsz3b8lgRcZEdA8jf9bxMal3+vWhrY/c3o7y0wiajx838ijYE=",
    "signing_algorithm": "RSA-PSS"
  },
  "jacsVersion": "8675c919-cb3a-40c8-a716-7f8e04350651",
  "jacsVersionDate": "2024-04-11T05:40:15.934777+00:00",
  "name": "Agent Smith"
}

You can verify you are set up with this command:

jacs agent verify  -a ./examples/agent/fe00bb15-8c7f-43ac-9413-5a7bd5bb039d\:1f639f69-b3a7-45d5-b814-bc7b91fb3b97.json

To make it easier to use, add jacs_agent_id_and_version to your config and you can just run

jacs agent verify

working with documents

Now that your agent is set up can create, update, and sign documents with your agent.

CLI

To create create documents, select a file or directory and the documents will be copied to jacs_data_directory and renamed.

jacs document create -d ./examples/raw/

Now you can verify a document is valid, even with custom JSON schema, and verify the signature of the document.

jacs document verify -f ./examples/documents/MODIFIED_e4b3ac57-71f4-4128-b0c4-a44a3bb4d98d\:975f4523-e2e0-4b64-9c31-c718796fbdb1.json

Or a whole directory

jacs document verify -d ./examples/documents/

You can also verify using a custom JSON Schema

 jacs document verify -f ./examples/documents/05f0c073-9df5-483b-aa77-2c3259f02c7b\:17d73042-a7dd-4536-bfd1-2b7f18c3503f.json -s ./examples/documents/custom.schema.json

If you share your public key, other agents can verify the document is from your agent , but is not available in the command line yet. Also, note that the command line doesn't yet allow for the modification of documents or agents.

To modify a document, copy the original and modify how you'd like, and then JACS can update the version and signature

jacs document update -f ./examples/documents/05f0c073-9df5-483b-aa77-2c3259f02c7b\:17d73042-a7dd-4536-bfd1-2b7f18c3503f.json -n examples/raw/howtoupdate-05f0c073-9df5-483b-aa77-2c3259f02c7b.json -o updatedfruit.json

Filenames will always end with "jacs.json", so the -o

You can embed external files

jacs document create -f ./examples/raw/not-fruit.json --attach ./examples/raw/mobius.jpeg --embed true

API

Agreements

Agreements are one of the basic reasons JACS exists. An agreement is a collection of signatures from required agents. You may want to use it to ensure that agents agree. You can also create human-in-the-loop scenarios, where automated agents sign, but the human using the cli must sign the document for a process to contineu.

If all the agreements are signed.

To create an agreement you need an existing jacs document and agent ids (no version):

jacs document verify -f  examples/documents/a3b935f3-57c4-4562-9d1a-2c06a89380e7\:4f041628-5a2d-48d3-aa17-a8bd9b9fc00e.json

Then create add a comma separated list of agents where -i are the agent identities.

jacs document create-agreement -f ./examples/documents/newjsonld.json -i 432e0415-5317-4999-abd4-f2a125dab90a, 5305e3e1-9b14-4cb7-94ff-902f9c101d91

To sign the document, sign the new document that was created by create-agreement

jacs document sign-agreement  -f  examples/documents/a3b935f3-57c4-4562-9d1a-2c06a89380e7\:1c37d69f-243a-45d2-aa99-c298af6b1304.json

Now you can check if the agreement was signed. If all agents have signed, it will continue, if not all agents have signed, it will error.

jacs document check-agreement  -f  examples/documents/a3b935f3-57c4-4562-9d1a-2c06a89380e7\:1c37d69f-243a-45d2-aa99-c298af6b1304.json

JSON schemas

Schemas IDs and Versions vs Signatures

IDs of agents and documents should be unique to your agent as they are a combination of ID and Version. However, if you share your documents, and we expect that you will, documents can be copied by other agents at any time and they can forge IDs and sign their docs.

Semantic versioning would break if the document forks because multiple agents will work on a single document. So each id/version is a UUID, and the previous version is stored so a trace can be constructed. (In itself, it's not a blockchain such that each version can be verified in the context of the previous version).

Schemas: basic types

Every JACS doc has a header. These are created automatically.

You only need to use the agents and header to record and verify permissions on any type of document. Here are the basic types.

  • Header - the signature along with permissions
  • Agents - a type of resource that can take action
  • Tasks -a set of actions and a desired outcome as well as state management, can reference other tasks
  • Signatures - cryptographically signed signature of the version of the document
  • Files - documents you can sign and "attach"

Security

JACS goal is to introduce no safety vulnerabilities to systems where it is integrated. Open to ideas on what cryptography to add next: https://cryptography.rs/, like https://doc.dalek.rs/bulletproofs/index.html.

filesystem

However, filesystem acces can also be turned off completely for documents. This means your app passing strings in and out of JACS but can not save().

By default a directory is used that is configured. JACS should not touch any files outside the key directory JACS_KEY_DIRECTORY and the JACS_DIRECTORY.

private keys

Private keys are stored in memory with https://docs.rs/secrecy/latest/secrecy/ The are also encrypted when on the filesystem if you have set the password with the keys are created.

header validation process

The following is a brief explanation of documents are created, signed, and verified.

signing

Signature options are "ring-Ed25519", "RSA-PSS", and "pq-dilithium". These are all open source projects and JACS is not an encryption library in itself.

  1. a json document is loaded as a "new" document
  2. as a new document it must not have an id, version etc
  3. an id and version uuid is created, along with date, etc
  4. all the fields are hashed and put into a field that is not part of the hash, and the hash is added
  5. all the fields are used to sign with the agent's private key, and the public keys sha256 is aded to the document, as well as the signing agent's id and version

verifying

  1. a document is loaded and is verified as being a jacs document using the schema
  2. the hash is checked by taking the value of the fields excluding signature areas, and checking the hash
  3. the agent id is used to find the public key of the document and the signature is checked

trust

When data is changed documents are versioned and the version is cryptographically signed by your agent. Changes can be verified and approved by other agents using your public key, allowing for creation and exchange of trusted data.

NOTE: Doesn’t require central key authority yet, but this does mean that anyone can spoof anyone. Until then, use for self signing only, or exchange public keys only with trusted services.

JACS should not need to make network calls for JSON schema as they are loaded into the lib.

JSON schemas

Schemas IDs and Versions vs Signatures

IDs of agents and documents should be unique to your agent as they are a combination of ID and Version. However, if you share your documents, and we expect that you will, documents can be copied by other agents at any time and they can forge IDs and sign their docs.

Semantic versioning would break if the document forks because multiple agents will work on a single document. So each id/version is a UUID, and the previous version is stored so a trace can be constructed. (In itself, it's not a blockchain such that each version can be verified in the context of the previous version).

Schemas: basic types

Every JACS doc has a header. These are created automatically.

You only need to use the agents and header to record and verify permissions on any type of document. Here are the basic types.

  • Header - the signature along with permissions
  • Agents - a type of resource that can take action
  • Tasks -a set of actions and a desired outcome as well as state management, can reference other tasks
  • Signatures - cryptographically signed signature of the version of the document
  • Files - documents you can sign and "attach"