Skip to content

Authenticate a Cloud Request Engine on a license key alone, and send the property list - #64

Merged
jwrosewell merged 8 commits into
rcfrom
align/license-key-alone
Nov 10, 2026
Merged

jwrosewell merged 8 commits into
rcfrom
align/license-key-alone

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On rc, CloudRequestEngine cannot be built on a license key alone and cannot be told which properties to ask for. It also puts a license key in the URL of both requests it makes.

The specification on rc at d729b7d, which holds specifications#128, #131 and #133, gives every combination in Accepted combinations.

Resource Key License Key Requested Properties Valid Reason
Yes No No Yes The Resource Key already states which Properties it carries.
Yes Yes No Yes The response holds what the Resource Key carries, and the License Key adds no Property.
Yes Yes Yes Yes The response adds the Requested Properties the License Key grants.
No Yes Yes Yes The License Key names no Properties, so the caller names the ones it wants.
No Yes No No The remote server answers 400 to such a request, so every request would fail.
Yes No Yes Yes Each requested Property is added, as null with a reason where no licence grants it.
No No Either No There is nothing to authenticate with, and the remote server answers 401.

The sections this change follows are listed here, all at d729b7d.

  • License Key says it is sent as license and "MUST NOT appear in full in a log entry or an error message".
  • Requested Properties says the list is sent as values, and that with a Resource Key and no License Key "each requested Property is added to the Properties the Resource Key carries", a Property the licence does not grant is answered as null with a nullreason, "and a name that is not a Property is not returned".
  • Accepted combinations says "A value that is empty or is only whitespace counts as absent".
  • Discovery under a License Key says an engine on a License Key alone "MUST make the accessibleproperties request with the License Key, sent as license in the body of a POST request rather than in the URL".
  • Processing says the form data carries the Resource Key as resource, the License Key as license and the list as values.
  • Properties the remote server did not return says an engine that sent a list MUST compare it with the answer, case insensitively, counting a null as answered, and report the difference once without failing the request. With a Resource Key, Requested Properties and no License Key, "A name the answer leaves out is then one that is not a Property, and the report says so rather than naming a License Key that was never given."
  • Logging, License keys asks for a test that a failed request carrying a license key logs and throws nothing holding the key in full.

#58 is merged. The license key masking draft #58 is on rc as efbea08, and rc is merged into this branch (8f9fa57). The cloud refuses a license key with an error that names it, and #58 masks the engine's own key in that text.

Change

In fiftyone.pipeline.cloudrequestengine and the pipeline builders.

  1. Options. The constructor takes requestedProperties, as a list or one comma separated string, with each name trimmed. A key that is empty or only whitespace counts as absent, and any other key is sent as it is given, as .NET (CloudRequestEngineBuilder.cs) and Java (CloudRequestEngineBuilder.java) send it.
  2. Build. The engine refuses only the two invalid rows, being no key at all (errorMessages.noCredential) and a license key with no resource key or list (errorMessages.licenseKeyNeedsProperties). Each message says why the cloud service would refuse every request. A resource key with a list builds, with or without a license key.
  3. Data request. A resource key still names the route. A license key alone posts to json, the route that takes none. The body carries resource, license and values where each is set, after the evidence so evidence cannot replace them.
  4. Discovery. With a license key, accessibleproperties is a POST with the keys in the body. A resource key alone fetches it with a GET as before. evidencekeys is unchanged and needs no key.
  5. Report. When a list was sent, the first answer is compared with it and the names left out are logged once as a warning. The request does not fail. With a license key the warning is errorMessages.propertiesNotCovered, which says the properties are not covered by the keys in use. With a resource key and no license key it is errorMessages.propertiesNotProperties, which says they are not properties the cloud service knows, as specifications#133 asks.
  6. Missing product. errorMessages.elementMissing, logged by the cloud aspect engines, now says the cloud service left the product out of the answer, without naming one cause, and elementNullNoReason says the cloud service gave no reason. Each is followed by a hint for the keys in use. Where a resource key is in use the hint points at accessibleproperties?resource=<key>. Under a license key alone it says the answer holds only the properties requestedProperties names that the license key includes, because a product is also left out when requestedProperties names none of its properties.
  7. Builders. The Device Detection and IP Intelligence pipeline builders and their cloud pipeline builders pass requestedProperties to the engine, and the location pipeline builder passes licenceKeys and requestedProperties, so a license key alone can be used through each of them. Before, none passed requestedProperties and the location builder passed no license key, so a builder caller with a license key and no resource key was refused with a message naming an option the builder could not pass.
  8. Documentation. The package readme.md gains a Credentials section, and the declarations in types/ cover the new messages and builder options.

Effect on existing callers

  • A resource key alone gets the same route and the same discovery request. The data request body now also names the key as resource, as the Processing section says, so the answer is the same.
  • A resource key with a license key gets the same answers, with the license key moved from the URLs into the bodies.
  • No resource key and no license key is still refused at build. The thrown value is now an Error whose message names the fix, rather than the string Cloud engine needs a resourceKey.
  • A key with spaces around it is now sent with them, where this draft's first version trimmed it.
  • The missing product messages read differently, as above.

Tests

In pipeline/fiftyone.pipeline.cloudrequestengine/tests, with a recording request client and no live key.

  • cloudRequestEngineCredentials.test.js covers every row, the URLs and bodies, the report, and failed requests. The failure stub now answers as the cloud does, Invalid license key(s) supplied: '<key>', and the test expects only ****************7890 in what is logged and thrown. New since the last review are a resource key with a list whose answer leaves out a name that is not a property, and a key with spaces around it kept as given.
  • cloudEngineMissingElement.test.js checks the missing and null element messages under a license key alone, and that the resource key message still gives the accessibleproperties hint.
  • builderCredentials.test.js builds a pipeline with a license key and a list through each of the five builders.

Runs

Run Head Result
Red first tests only on rc, edb6601 14 of 63 failed, every one a new behaviour
Green first tests and code, c4c34f4 63 passed, eslint clean, tsc declarations identical
Red the new tests on the previous head, 2c84e79 9 of 75 failed, being the five builders (each refused the license key for want of requestedProperties, and location for want of any key), the not a property report, the two license key alone messages and the key kept as given
Green the head 2ff6f89 75 passed in 10 suites, eslint clean
Red the reworded message tests on 6d9b96e, which merges rc at f88193d 2 of 81 failed, both expecting the product to be "left out of the answer"
Green the head ddc33b9 81 passed, eslint clean
Full build draft head ddc33b9 every job passed, being Build and Test on Ubuntu, Ubuntu ARM and Windows with Node 22 and 24, Configure printed "Left out 2 macOS entries", and all 7 Setting 'PullRequestSha' lines are ddc33b9

macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.

Against the issue

The issue's list of what a change has to cover, written before the specification was corrected, is answered below.

  1. License key and property list accepted. Done.
  2. Invalid combinations refused at build, blank values absent. Done, for the two rows the corrected table refuses.
  3. resource, license and values sent on the data request. Done.
  4. Evidence named values, resource or license left out. Left to the reserved Evidence draft, Never send resource, license, licence or values from Evidence to the cloud #61, whose lines this draft keeps away from.
  5. Skip accessibleproperties under a license key alone. Superseded by specifications#128, which measured a 200 answer to a POST carrying the key, so discovery now posts it.
  6. Report the properties the answer left out, once. Done, worded as specifications#133 asks.
  7. Unit tests for every row. Done. The live test is not added, see below.

What remains

  • A live test on a license key alone. This repository's live tests never skip (liveCloudKeys.js), so one needs a license key entitled to cloud properties in CI, and I could not confirm that the key CI holds is one.

For #7

…the property list

The engine builds on a license key with requestedProperties, and sends
the list as values whenever one is given, beside a resource key too. It
refuses at build only what the cloud service refuses on every request,
being no key at all and a license key with no resource key or list.

The keys now travel in the body of the data request, as resource and
license, and a license key is never put in a URL. The accessible
properties request posts the keys when there is a license key, and a
resource key on its own fetches them as before. The resource key still
names the data route.

When a list was sent, the first answer is compared with it, and the
names the answer left out are logged once as not covered by the keys.
…ey text

- A resource key with a property list and no license key reports a name
  the answer leaves out as not a Property, as specifications#133 says.
- Under a license key alone the missing element and null element
  messages name the key in use and requestedProperties, and no resource
  key.
- Every pipeline builder that adds a Cloud Request Engine passes the
  license key and the requested properties.
- The failure test's stub names the license key, as the cloud's refusal
  does, and the test expects only the masked form.
- A key that is not blank is kept as given rather than trimmed.
… builders

- With a resource key, requested properties and no license key, a name
  the answer leaves out is not a property, as specifications#133 says,
  so it is reported as one the cloud service does not know rather than
  as one the keys do not cover.
- The missing element and null element messages say the key in use does
  not include the product, and give the accessibleproperties hint only
  where a resource key is in use. Under a license key alone they say the
  answer holds only the properties requestedProperties names that the
  license key includes, as the Python package words it for either key.
- The Device Detection, IP Intelligence and location pipeline builders
  pass requestedProperties to the Cloud Request Engine, and the location
  builder passes licenceKeys too, so a license key alone can be used
  through each of them.
- A key that is not blank is sent as it is given, as .NET and Java send
  it, where it was trimmed. A blank key still counts as absent.
- Two comments no longer say "as it always has".
Under a license key alone a product is also left out when
requestedProperties names none of its properties, so the message says
the cloud service left the product out of the answer, and the hint that
follows gives the causes.
…mple

The missing product message said the key in use does not include the
product, and the comment beside it said the resource key does not.
Under a license key alone the product is also left out when
requestedProperties names none of its properties, so the message now
says the cloud service left the product out of the answer, and the hint
that follows it gives the causes for the keys in use. The IP
Intelligence builders' requestedProperties documentation gave a device
property as its example, and now gives ip.registeredcountry.
@jwrosewell
jwrosewell marked this pull request as ready for review November 10, 2026 20:27
@jwrosewell
jwrosewell merged commit a8f1c22 into rc Nov 10, 2026
2 checks passed
@jwrosewell
jwrosewell deleted the align/license-key-alone branch November 10, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant