Download the PHP package phox/jev-secrets without Composer

On this page you can find all versions of the php package phox/jev-secrets. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package jev-secrets

jev-secrets

Replaces names, keys and other secrets in a Jev request with stand-ins before it is sent, and puts the originals back in the answers. For the PHP SDK and the official JavaScript and Python SDKs, or any code that builds the request body itself.

The second line is what Jev sees, with John Smith passed as a value and the rest found by the default patterns. In each replaced word every letter becomes another letter of the same case, vowels stay vowels, digits become digits, and punctuation stays, so a name still reads as a name and an email address as an email address. The same word gets the same stand-in everywhere in the request, including in the questions. The answers come back with the original question ids and choice labels.

This is pseudonymisation, not anonymisation: the mapping is held in memory in order to be able to reverse the process on the way back to the caller.

Contents: What gets replaced · The key · Config · What it does not do · Does it change the answers?

Install

Tested on SDK versions the wrapper is tested with
PHP 8.3, 8.4, 8.5 phox/typesafe-sdk-php 0.3 and 0.4
JavaScript Node 20.19, 22, 24 @typesafe-ai/sdk 0.5.7 and 0.6.0
Python 3.10 to 3.14 typesafe-sdk 0.7.0 and 0.7.1

A request of 1000 strings, 500 KB of JSON, takes 0.4-0.5 s in PHP and JavaScript and 1.1-1.4 s in Python; docs/performance.md has the measurements.

Use

With the SDK, wrap the client. Each call takes the values to hide in that request, on top of whatever the config finds:

jev_secrets.typesafe.AsyncSecretClient wraps the async Python client. The wrappers sit above the SDK, not in its transport, because the SDKs log request bodies at debug level before the transport sees them.

Any config option can be changed at call time. scope and dates merge entry by entry; any other option given replaces the configured one:

In JavaScript it is options.overrides, in Python overrides=, and without an SDK the third argument of pseudo().

Without an SDK, rewrite the body yourself and restore the decoded response:

pseudo() is also available as pseudonymise(), pseudonymize() and mask(), and restore() as unmask().

$done->replacements lists what was replaced, as a path into the sent request and the source that found it, without the values themselves.

What gets replaced

The sources, all optional:

Source What it matches
Values passed to the call those strings
Config terms (fixed strings), fields (paths whose whole value is replaced), patterns (your regexes)
Defaults the patterns below, and the value under a key such as password, token or api_key

secretKeys controls those key names: false for none, a list for exactly those, or {"add": [...], "remove": [...]} to change the default list. Names compare lowercased, ignoring spaces, hyphens and underscores, so member_number covers Member-Number.

Values and terms match case-insensitively, at word boundaries. Their words may be joined by any run of spaces, underscores, hyphens or dots, so Ellen Park is also found in is_from_ellen_park and [email protected]. A value shorter than 2 characters is refused. The value found at a field path is also replaced wherever else it appears in the request.

Names cannot be found by pattern. Pass them as values, list them as terms, or name the fields they're in.

Dates, and numbers the default patterns do not cover, are not replaced by default. Pass one as a value, or name its field, and a number is replaced digit by digit, a date or time moved (below). With dates.detect: true every date and time in the request is moved.

Default pattern Finds
email an email address
ipv4 a dotted-quad IPv4 address
ipv6 an IPv6 address, full or compressed, with at least one decimal digit
card a card number of 12 to 19 digits that passes the Luhn check
iban an IBAN that passes the mod-97 check
phone a phone number written with a leading + and 8 to 15 digits
us-ssn a US Social Security number written with dashes
uk-nino a UK National Insurance number
aws-access-key an AWS access key id, keeping its prefix, such as AKIA
github-token a GitHub token, keeping its prefix, such as ghp_
github-pat a fine-grained GitHub token, keeping the github_pat_ prefix
stripe-key a Stripe secret or restricted key, keeping its prefix, such as sk_live_
slack-token a Slack token, keeping its prefix, such as xoxb-
anthropic-key an Anthropic API key, keeping its prefix, such as sk-ant-api03-
openai-key an OpenAI API key, keeping its prefix, such as sk-proj-
google-api-key a Google API key, keeping the AIza prefix
jwt a JSON Web Token, keeping the leading eyJ
private-key the body of a PEM private key, keeping the BEGIN and END lines
bearer-token a bearer token of 16 or more characters, keeping the word Bearer
credential-assignment a value after password=, api_key:, token= and the like in text, keeping the name

Where two matches overlap they merge, so a value inside an email address takes the rest of the address with it. catalogue/patterns.json holds the patterns and the key names; the PHP, JavaScript and Python implementations read the same file.

What a stand-in looks like

Recorded outputs of the character generator under a fixed key, from catalogue/fixtures.json:

Input Stand-in
John / JOHN Tozd / TOZD
O'Brien-Smythe I'Ghees-Dmjcbu
José Müller Taré Hömsif
Дмитрий Иванов Ьхэвлаӗ Ычозюв
김민준 펇쫹떀
2024-12-31 23:59 1011-11-21 12:33
10.0.0.1 22.9.9.7

A stand-in is drawn again until it differs from every word already in the request and from every other stand-in. Short numbers under the digit rule can run out of stand-ins and share one; docs/generation.md has the exact rules.

The key

Stand-ins and date offsets are drawn under a key:

key What each call uses
left out the JEV_SECRETS_KEY environment variable, read on every call; without it, a random key
a string that string
false a random key, whatever the environment holds

With a random key the stand-ins change from call to call. With a fixed one the same request gives the same stand-ins every time, in every implementation. Nothing is stored between calls, so rotating the key costs nothing: calls after the change get different stand-ins. The library reads the process environment, not a .env file; load that the way your framework does.

What is rewritten and restored

Part of the request Rewritten Restored in the answers
state strings and numbers yes -
state object keys with scope.keys -
question instructions and criteria text yes a score's legend, exactly as sent
question ids where they contain a match the answer keys
choice labels where they contain a match choice and the keys of probabilities
noul criteria keys, type, model, anything else at the top level never -

A score's legend keys and probability keys are rubric indices and are never restored, nor is any number in the response. A string field in an answer that this library does not know gets word-by-word replacement of the stand-ins.

Config

The same object in PHP, JavaScript and Python. spec/config.schema.json has every option and its default.

allow protects a string from terms, fields, patterns and the defaults; a value passed to a call still replaces it.

When it refuses to send

After rewriting, every original value is looked for again across every string and key under state and questions. If one is still there, the call throws LeakException (LeakError in JavaScript and Python) and nothing is sent. The message names the path and the source, never the value, and suggests the fix for the usual causes: a value in an object key while scope.keys is off, or in the questions while scope.questions is off.

In PHP, a request that cannot be searched is refused too: text that is not valid UTF-8, or a regex that stops at PCRE's backtrack limit (MatchException). Matching cannot say what it missed, so nothing is sent. JavaScript and Python strings are always Unicode, and their regexes have no such limit.

A config that cannot work is refused when it is made: an unknown option, a pattern that does not compile, a term with no letter or digit or shorter than minLength. A value passed to a call is checked the same way when the call is made.

What it does not do

Does it change the answers?

Over 67 labelled questions on 50 PII-heavy requests (docs/evidence.md):

Documentation

docs/dates.md are the byte-level contract the implementations share. catalogue/fixtures.json holds the cases each must reproduce: php scripts/golden.php records them from the PHP implementation, and the JavaScript and Python suites require the same output.


All versions of jev-secrets with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
ext-intl Version *
ext-json Version *
ext-mbstring Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package phox/jev-secrets contains the following files

Loading the files please wait ...