| Summary || Products || Cryptography || Fusion || KeeeX.Js || Verifier || KeeeX Chain || Digital Identity Management |
| Description || Quickstart |
KeeeX Fusion, the tool used to process any file and create proof-bearing files, is available exclusively to our customers.
This page serves as a quick guide to help technical users understand its ease of use and deployment options.
A full quick-start guide is also available.
KeeeX Fusion is offered in two modalities:
The command-line tool is provided as a Linux binary for either x86_64 or certain arm architectures upon request.
It is distributed via a private file-sharing service that supports notifications for version updates.
The Docker image is hosted in our private repository, and individual credentials are provided when necessary.
Available for download (for registered customers) are the binary and its signature, signed with our software signing GPG key, which has the following fingerprint:
200419574E37E6C613061F57BDD467B14844B41D
The latest version at the time of writing this guide is named fkeeex.v7.1.5.linux.
The entire application is bundled into a single file that can be moved and renamed as necessary.
Assuming you have gpg installed, you can verify the authenticity of the distributed file with a single command:
gpg --verify fkeeex.v7.1.5.linux.sig
gpg: Signature made Wed Mar 12 12:38:58 2025 CET
gpg: using EDDSA key 200419574E37E6C613061F57BDD467B14844B41D
gpg: Can't check signature: No public key
You can compare the key fingerprint with the value above.
To automate the process, you can register our public key in your own keyring or use the key file directly.
Our software signing public key file is available as an asc file.
To use it to verify signatures directly:
gpg --no-default-keyring --keyring ./keeex_software_key.asc --verify --verify fkeeex.v7.1.5.linux.sig
gpg: Signature made Wed Mar 12 12:38:58 2025 CET
gpg: using EDDSA key 200419574E37E6C613061F57BDD467B14844B41D
gpg: Good signature from "KeeeX software signing key <certmaster@keeex.net>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 2004 1957 4E37 E6C6 1306 1F57 BDD4 67B1 4844 B41D
The bare minimum configuration requires a valid username and password, which are provided by KeeeX.
The simplest method is to set these credentials in a configuration file in JSON format:
{
"user": "<valid keeex login>",
"password": "<associated password>"
}
Other options exist but are outside the scope of a quickstart guide.
It is also possible to use some environment variables:
FKEEEX_CONFIG: path to the configuration JSON file, if used.FKEEEX_CONFIG_USER: value for the user name.FKEEEX_CONFIG_PASSWORD: value for the password.If you have a PNG file named input.png, you can use the following command:
./fkeeex.v7.1.5.linux -c <config path> -a keeex -d '{"src":"input.png","dst":"output.png", "options": {"timestamp": true}}'
{
"mainIdx": "xumil-cuziz-pevyg-fesyl-melar-fecyc-behor-natol-bafez-dysob-badah-kiseg-dupag-kupeb-hilos-votek-voxix",
"timestamp": {
"anchors": [],
"idx": "xumil-cuziz-pevyg-fesyl-melar-fecyc-behor-natol-bafez-dysob-badah-kiseg-dupag-kupeb-hilos-votek-voxix",
"timestampRequestDate": "2025-04-08T16:30:19.432Z"
}
}
(Note that if you've set up the config file using environment variables, you do not have to provide it on the CLI again.)
This will create an output file named output.png, which behaves exactly as expected for a PNG file.
However, this file now also carries a digital proof with its unique digital identifier and is timestamped using multiple methods, providing undeniable evidence of its existence at a specific point in time.
In addition to timestamping, an essential aspect of authenticity checks is using digital signatures.
The acquisition of a digital signature key is beyond the scope of this document.
Various systems, ranging from self-managed setups to extensive large-scale PKI infrastructures, are all valid options.
KeeeX Fusion operates independently of the way you obtain your keys; the important part is that you can produce a digital signature with them.
For this example, we'll use an extremely basic (yet entirely realistic) use case: generating a digital signature key from a passphrase.
As a security note, while using passphrases to generate digital signatures is secure in itself, it is only as secure as the chosen passphrase; it must be unique, long, and never shared with outsiders.
Furthermore, this approach requires additional effort to ensure that your digital signature is recognized by others.
Nevertheless, for a quick start guide, we'll use a passphrase to inject a digital signature into the output file.
Use the following command:
./fkeeex.v7.1.5.linux -c <config path> -a keeex -d '{"src":"input.png","dst":"output.png", "mdata":{"identities":[{"type":"bitcoin","passphrase":"secret passphprase goes here"}]}, "options": {"timestamp": true}}'
{
"mainIdx": "xulet-vamic-herem-civag-kahub-ripag-lipib-tuhac-filem-capid-lysus-fazyd-bovek-rypev-seror-rizup-buxix",
"timestamp": {
"anchors": [],
"idx": "xulet-vamic-herem-civag-kahub-ripag-lipib-tuhac-filem-capid-lysus-fazyd-bovek-rypev-seror-rizup-buxix",
"timestampRequestDate": "2025-04-08T16:35:54.890Z"
}
}
Note that this action would overwrite the previous file if performed with the same output name.
Additionally, although it mentions "bitcoin," this digital signature does not rely on Bitcoin's public blockchain infrastructure.
We, however, leverage the digital signature and other cryptographic algorithms used to secure Bitcoin transactions to take advantage of possible audits and scrutiny these algorithms are subjected to.
The -d CLI argument contains all the details of the operation and now includes an mdata.identities property, which stores our passphrase.
Now that your file has its own authenticity metadata, you can validate it from anywhere.
In fact, anyone with access to our verification tools (which include a public online website and other options) can do so.
To verify a file using the CLI tool, simply use a single command:
fkeeex -a verify -d '{"src":"output.png"}'
{
"identities": [
{
"address": "13u4KzWq3ornY3kRy1HhFEjAFcYZgYV9N9",
"keyAddress": "13u4KzWq3ornY3kRy1HhFEjAFcYZgYV9N9",
"optional": false,
"signable": "2025-04-08T16:35:54.842Z|xulet-vamic-herem-civag-kahub-ripag-lipib-tuhac-filem-capid-lysus-fazyd-bovek-rypev-seror-rizup-buxix",
"signature": "G2WGySycKSStSEICYM1IyjLHNb4JYKr6SvE5fZ1yse+J3vLJiDl9vhjJb7BUXqUq5s0vswCn239k9dTSW3DtRxc=",
"status": "VALID",
"topicId": 0,
"type": "bitcoin",
"timestamp": "2025-04-08T16:35:54.842Z"
}
],
"idxs": [
{
"algorithm": "sha3-256+sha256",
"encoding": "bubble-babble",
"main": true,
"recursive": false,
"value": "xulet-vamic-herem-civag-kahub-ripag-lipib-tuhac-filem-capid-lysus-fazyd-bovek-rypev-seror-rizup-buxix"
},
{
"algorithm": "sha256",
"encoding": "hex",
"main": false,
"recursive": true,
"value": "50cf3f6b75a4ae008ffe013f6d7984a35d5b2fbcee26b363c06879e8cfa5900c"
}
],
"license": {
"licenseDate": "2025-04-08T16:35:54.488Z",
"licenseMode": "online",
"licenseText": "Protected By KeeeX",
"userIdx": "ximav-kerim-levym-mihyk-fagok-kokod-pykar-zobol-mydic-cepoc-hecym-sopap-fovib-hesyg-zomyv-kynic-taxex"
},
"mainIdx": "xulet-vamic-herem-civag-kahub-ripag-lipib-tuhac-filem-capid-lysus-fazyd-bovek-rypev-seror-rizup-buxix",
"name": "",
"properties": {
"kx.description": {
"value": ""
},
"kx.author": {
"value": ""
},
"kx.afterbc": {
"value": "BC|ETH.main|22225415|a7fb56a95262329d509be02719783dc857046562bdba83929fb5b1cd49dcbca3|2025-04-08T16:35:38.150Z"
},
"kx.time": {
"value": "2025-04-08T16:35:54.780Z"
}
},
"statementVersion": "2",
"status": "VALID",
"target": "prod",
"appVersion": "@keeex/js-fusion@7.1.5",
"time": "2025-04-08T16:35:54.780Z",
"afterBc": {
"date": "2025-04-08T16:35:38.150Z",
"text": "Block #22225415 from Ethereum at 2025-04-08T16:35:38.150Z: a7fb56a95262329d509be02719783dc857046562bdba83929fb5b1cd49dcbca3",
"checkUrl": "https://live.blockcypher.com/eth/block/a7fb56a95262329d509be02719783dc857046562bdba83929fb5b1cd49dcbca3/",
"height": 22225415,
"blockchainName": "Ethereum",
"hash": "a7fb56a95262329d509be02719783dc857046562bdba83929fb5b1cd49dcbca3"
}
}
We obviously won't go into all the details provided here.
However, the gist is:
mainIdx property represents the unique identifier for the file.status property should be set to VALID, indicating that all embedded authenticity data are valid and have not been altered.identities property contains information about the signatories (only one in this example), including their key "address" and the status of their signatures.Most digital signatures are created using asymmetric cryptography, which relies on a fundamental concept: each signatory owns a private key and a public key.
The private key is kept secret and must never be shared with third parties.
Conversely, the public key should be shared and associated with the signatory.
The creation of a digital signature requires the use of the private key, known only to the signatory.
Verification of the digital signature can be performed by anyone who has access to the signatory's public key.
In the case of KeeeX Fusion, the origin of such a keypair is not relevant to the keeexing process.
KeeeX refers to the public part of a digital signatory’s key as a "key address", which is related to public keys.
(For the purpose of this explanation, the terms "public key" and "key address" are interchangeable.)
In our example, we used a simple passphrase to act as the private key, and the generated "key address", which will be the same every time the same passphrase is used, is "13u4KzWq3ornY3kRy1HhFEjAFcYZgYV9N9".
In this example, the signatory would need to manually publish this address somewhere and associate it with his name so that any third party could verify his signature.
In cases where an existing key management system is in place, it is the responsibility of that system to provide such information.
A common example is the use of a shared PKI (Public Key Infrastructure) that issues trusted certificates.
These certificates link a public key with a name and are themselves signed by a trusted issuer, creating a chain of trust that leads back to a trusted third party agreed upon by all parties involved.
This concludes the CLI quick start guide.
It is extremely easy to process a file and add data to it.
The verification process shows a properties property.
Users can add custom values in that field, which will be extracted during the verify action.
These custom values are free-form and guaranteed to be authentic as long as the file status is valid and the signatories are trusted.
By leveraging this mechanism, additional metadata can be embedded into many file formats without altering their original behavior.
Our KeeeX Fusion tool is also available as a Docker image for integration into container-based deployments.
As usual, you must log in to our private repository using the provided identifier:
docker login repo.keeex.me
Retrieving the image can be done using any of these tags:
repo.keeex.me/fkeeex_daemon:latestrepo.keeex.me/fkeeex_daemon:v<full semver>repo.keeex.me/fkeeex_daemon:v<major version>The major version at the time of writing is 7.
Since we occasionally publish patches, it is recommended to stay on a given major version during unattended upgrades.
Forward compatibility for all operations within a specific major version is guaranteed.
Currently, our startup script will look for the UID and GID environment variables and attempt to change its own user/group accordingly.
Alternatively, you can specify a user and group when running the image using Docker's standard configuration options.
To configure the KeeeX username and password as described in the CLI section of this page, use the following environment variables:
FKEEEX_CONFIG_USER: value for the usernameFKEEEX_CONFIG_PASSWORD: value for the passwordNote that the service starts in the /srv directory within the container.
External volumes can be mounted, and relative paths from the /srv directory are also supported.
Finally, the process listens on port 8080.
Using low-level Docker commands, running the service can be as simple as:
docker container run -d -p 6000:8080 repo.keeex.me/fkeeex_daemon:v7
This will run the container and listen on port 6000 for incoming requests.
curl -X POST --header "Content-Type: application/json" --data '' http://localhost:6000/status
{"apiStatus":{"reachable":true,"reachableWithoutProxy":true},"configStatus":{"config":{"defaultIdentity":"<undefined>","license":"<undefined>","password":"<undefined>","proxy":"<undefined>","user":"<undefined>"},"haveCredentials":false,"haveDefaultIdentity":false,"haveProxy":false},"credentialsStatus":"<undefined>","issues":[],"licenseStatus":"<undefined>","status":"verifyOnline","version":{"current":"7.1.3","latest":"<undefined>"}}%
The above indicates the expected output when calling the status POST route in this case.
To properly use the image, a login and password configuration must be passed using the -e option:
docker container run -d -e FKEEEX_CONFIG_USER=login -e FKEEEX_CONFIG_PASSWORD=password -p 6000:8080 repo.keeex.me/fkeeex_daemon:v7
Running the above call to /status would return updated information, indicating whether the credentials are correct.
Since the KeeeX Fusion Docker image is relatively lightweight, requires only a few environment variables to operate, and is available through a standard repository, it can be deployed on any platform that supports Docker.
For example, this includes usage with Docker Compose files, Docker Swarm, or fully managed solutions.
Assuming you have the service running on port 6000, you can perform calls similar to those described in the CLI with the following adjustments:
-a parameter) corresponds to the route name (e.g., "/keeex", "/verify").multipart/form-dataUsing the service as a pure API service, you can base your usage on the following CURL call:
curl -v -f \
-F "file=@input.png" \
-F data='{"src":"-","dst":"-","mdata":{},"options":{"timestamp":true}}' \
-o output.png \
http://localhost:6000/keeex
This call will function similarly to the CLI call above, as it will keep the file input.png and output its content into output.png, from the caller's side.
It is required to pass - as both src and dst to indicate that the input and output come from the HTTP request.
Note that in this case, a custom header called X-KeeeX-Result is added to the reply, containing the output one would get on the terminal when making a CLI call.
application/jsonBy mounting an external volume into the container, it is possible to send a simple JSON body, similar to the CLI example provided above.
Doing so allows the command to run as intended, and by leveraging shared storage between KeeeX Fusion and the calling service, performance can be significantly improved.
curl --request POST \
--header "Content-Type: application/json" \
--data '{ \
"src":"data/input.png", \
"dst":"data/output.png", \
"mdata":{}, \
"options":{"timestamp":true} \
}' \
-o "result.json" \
http://localhost:6000/keeex
Assuming an existing container deployment of the service leveraging KeeeX Fusion, adding a Fusion container to each service container and sharing a temporary storage in this manner can provide significant improvements over sending input and output via HTTP queries.
Like the CLI, additional features are available.
The Docker container can utilize all CLI features.
When using the CLI, it is also possible to take advantage of the same API; however, this exceeds the scope of this document.
KeeeX Fusion, and our keeexing process, allows a lot of advanced use cases.
Here are some of the most useful ones outlined: