Skip to main content

Resource filtering

Resource filter expressions let you narrow a fleet-wide list with a CEL expression instead of a fixed set of query parameters. You pass the expression in the filter query parameter and Hub compiles it to SQL, so filtering happens in the database rather than in your client.

conditions.ready.status == "False" && createdAt > now() - duration("24h")
note

Resource filter expressions is an alpha feature. Its grammar and available fields may change in incompatible ways between releases. See the feature lifecycle.

Where you can use it

EndpointNotes
GET /apis/hub.upbound.io/v1beta1/resourcesCurrent version.
GET /apis/hub.upbound.io/v1alpha2/resourcesSame filter schema as v1beta1.
GET /apis/catalog.hub.upbound.io/v1alpha1/imagesDifferent field set. Requires the Catalog gate.
POST /apis/catalog.hub.upbound.io/v1alpha1/imagesearchesTakes the expression in spec.filter. Requires the Catalog gate.

hub.upbound.io/v1alpha1/resources doesn't accept filter at all. It takes discrete per-field parameters instead, such as kind, controlPlane, ready, and labelSelector. It ignores a filter key without an error. Use v1beta1 for expression filtering.

Available fields

You can use these fields in a filter expression on the resources endpoints:

FieldTypeNotes
kindstring
groupstring
apiVersionstringThe version segment only, such as v1beta1. Not group/version.
namestring
namespacestring
labelsmap(string, string)
annotationsmap(string, string)
controlPlanestring
realmstring
spacestring
crossplaneTypestringOne of xr, mr, composed, claim.
conditions.ready.statusstringTrue, False, or Unknown.
conditions.ready.messagestring
conditions.synced.statusstring
conditions.synced.messagestring
conditions.healthy.statusstring
conditions.healthy.messagestring
createdAttimestamp
updatedAttimestamp
deletedAttimestamp

There's no status field and no free-form access to the resource object. An unknown identifier is an error, not an empty match.

Supported operators and functions

CategorySupported
Boolean&&, ||, !
Comparison==, !=, <, <=, >, >=
Membershipin
StringstartsWith, endsWith, contains, matches
Conversiontimestamp(), duration(), int(), string()
Timenow()

The API rejects anything outside this list. That includes CEL macros such as exists, all, map, and filter, ternary expressions, and arithmetic beyond timestamp and duration math. The expression as a whole must evaluate to a boolean.

How filtering behaves

Hub compiles the expression to a SQL WHERE clause and applies it before pagination, so page and pageSize page through the matches. The total in the response metadata is the filtered count, not the fleet count.

Filtering never widens access. The expression is evaluated against the resources the caller is already authorized to see, so a filter can't surface a resource in a realm the user can't view.

Limits

LimitValue
Expression nesting depth50
Regex pattern length in matches()1000 characters

There's no cap on overall expression length.

See also