Blog

Engineering

How Jigward keeps your credentials out of the model

Jigward can sign in to your app, call your API and read your AWS logs without the model ever seeing a password, a key or an AWS credential. How each works, and the two places the rule stops.

To check your staging app, Jigward has to sign in. To use your internal API, it needs a key. Most teams would rather not paste either into a chat window, and they are right: a secret that a model reads can end up in a report, a pull request description or a Slack thread without anyone deciding it should.

Jigward’s rule is that a secret a member gives it is used by Jigward’s own code and is never part of what the model reads, writes or keeps. The rule is not enforced by asking the model to be careful. It is enforced by where the secret is allowed to travel.

In practice that means three things today:

  • the values a browser profile types, such as a login and a password;
  • the key of a custom integration, the connection to your own HTTP API;
  • access to AWS CloudWatch Logs, where Jigward keeps no credential at all.

Signing in to your app: the model names a field, Jigward types the value

An admin sets up a browser profile: a name, one or more https addresses, the one Context whose Tasks may use it, and the values Jigward may type there. A Context is one area of work, such as a product’s backend, with its own repositories and Tasks. Each value has a key such as LOGIN or ADMIN_PASSWORD, an optional description of what it is for, and the value itself. Every value is hidden on screen until a member asks to see it.

When a Task signs in, the model sees the keys and descriptions, never the values. To fill in a form, it names a field on the page and the key it wants. Jigward’s own code fetches the value and hands it straight to the browser. The tool’s answer, the step and the log carry the key alone. A value is typed only into the profile’s own sites, and it is masked in every step, recording and log the session keeps.

Calling your API: the key goes into the request and comes out of the answer

A custom integration connects a system with an HTTP API at a public address. Jigward reads the API’s public documentation and drafts its operations, and an admin connects it by entering the address and the key in a form, never in a conversation.

From then on, Jigward’s code puts the key into each request. It is sent only to the saved address, follows no redirect, and is never used with another address.

The answer is where secrets usually leak, because APIs echo what they were sent. Before the model reads an answer, Jigward replaces the key with a placeholder in three forms: as it is, in Base64, which is how a basic authentication header comes back, and percent-encoded, which is how a key sent in a query string comes back inside links. A secret too short to mask safely is refused when it is entered. Masking is a second line of defense: the first is that the key is never logged or recorded.

Every request is recorded before it is sent, and the record holds no query string, header or body, and nothing the API answered.

Reading your logs: no credential kept

For CloudWatch Logs there is no secret to protect. An admin gives the account id, the regions and the log group prefixes Jigward may read. Jigward then provides a link that creates a role in that account, under the admin’s own AWS sign-in. The role may read logs under those prefixes and nothing else, trusts one identity of Jigward’s alone, and can be assumed only with an identifier Jigward generated for that connection.

Jigward asks AWS for short-lived access each time it reads, and the account’s own audit trail records every read. Disconnecting the account in Jigward stops Jigward from using it. Deleting the role in AWS is what takes the access away.

Where the rule stops

The rule is about the model. It is not a claim about everything a Task touches.

  • A screenshot shows what the page shows. A page that displays a credential shows it in the screenshot. For a Task given in Slack, screenshots follow the report into the thread, where everyone in the channel can see them.
  • What the model read is not protected the same way. A run that read a page telling it to can still send what it read to a public address it fetches. The key stays out of reach; the content the model read does not.
  • The workspace is not isolated yet. Repository code that runs in a Task’s workspace still reaches the public internet directly. Isolating it is designed and not yet applied.

No certification or attestation is claimed for any of this. These are mechanics, written down so each one can be checked. The Browser, Custom API and AWS CloudWatch Logs pages list what each integration is granted.