---
openapi: 3.0.0
servers:
- url: 'https://example.domain/'
info:
title: Fence OpenAPI Specification
version: 0.1.0
description: >-
Access management for Gen3 data commons. Code is available on
[GitHub](https://github.com/uc-cdis/fence).
termsOfService: 'http://cdis.uchicago.edu/terms/'
contact:
email: [email protected]
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: oauth2
description: Authorization and token management
- name: user
description: User information
- name: logout
description: Log out the current user
- name: data
description: Generate signed URLs
- name: credentials
description: Access credentials
- name: credentials/google
description: Google Credentials
- name: credentials/cdis
description: Deprecated! Use credentials/api
- name: credentials/api
description: API Credentials
- name: 'credentials/{provider}'
description: Other provider credentials
- name: link
description: Link access identities
- name: google
description: Google functionality
- name: keys
description: Get public keys used to validate JWTs issued by fence
- name: system
description: System endpoints
paths:
/_status:
get:
tags:
- system
summary: Returns if Fence is healthy or not
description: >-
Health check endpoint
produces:
- application/text
responses:
'200':
description: Healthy
default:
description: Unhealthy
/_version:
get:
tags:
- system
summary: Returns the version of Fence
produces:
- application/json
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/SystemVersionOutputRef'
/metrics:
get:
tags:
- system
summary: Get Prometheus metrics
description: >-
Returns Prometheus metrics if the `ENABLE_PROMETHEUS_METRICS` setting is `True`.
By default, this endpoint is public. Authorization controls can be setup externally;
in cloud-automation setups, access to this endpoint is blocked at the revproxy level.
responses:
'200':
description: successful operation
/oauth2/authorize:
get:
tags:
- oauth2
summary: Perform OAuth2 authorization
description: |
**IMPORTANT NOTE**: These docs are provided as a courtesy but do _NOT_ include the entirety of the OIDC Standard
simply because of its length and complexity.
Please [refer to the standard](https://openid.net/specs/openid-connect-core-1_0.html) for complete details.
Obtain an authorization grant through the OAuth2 protocol. To handle
this request, render a page for the user to confirm the OAuth2 grant
(through e.g. Google). Redirect user to `redirect_uri` with an added
`code` parameter obtained from the authorization provider.
operationId: authorize
parameters:
- name: client_id
required: true
in: query
description: 'The client''s ID, issued by authorization server'
schema:
type: string
- name: response_type
required: true
in: query
description: >-
For an authorization request using the access code flow, the
response type must be "code". If this is missing from the request
then the authorization server must return an error.
schema:
type: string
- name: redirect_uri
required: true
in: query
description: Page to redirect to after access has been granted
schema:
type: string
- name: idp
required: false
in: query
description: >-
Upstream identity provider to use. Specifying `idp=fence` lets
us specify a `fence_idp`. Specifying `idp=shibboleth` lets
us specify a `shib_idp`. If no `idp` is specified, defaults to
the configured default login.
schema:
type: string
example: 'google'
- name: fence_idp
required: false
in: query
description: >-
Upstream identity provider to use. Specifying `idp=fence` and
`fence_idp=shibboleth` lets us specify a `shib_idp`. If no
`fence_idp` is specified, defaults to NIH login.
schema:
type: string
example: 'shibboleth'
- name: shib_idp
required: false
in: query
description: >-
Identifier for the shibboleth IDP. Available identifiers are what
is listed by the `login.bionimbus.org/Shibboleth.sso/DiscoFeed`
endpoint. If no `shib_idp` is specified, defaults to NIH login.
schema:
type: string
example: 'urn:mace:incommon:uchicago.edu'
- name: scope
required: false
in: query
description: |
Requested authorization scope. Must include `openid`. `user` allows getting a user's access information.
> NOTE: This is required for [OIDC](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest)
schema:
type: string
- name: upstream_expires_in
required: false
in: query
description: |
the time (in seconds) during which the upstream refresh token (eg. RAS) is valid. Must be less
than the configured maximum. If it's greater,
the configured maximum will be used.
schema:
type: string
responses:
'200':
description: successful operation
post:
tags:
- oauth2
summary: Perform OAuth2 authorization
description: |
**IMPORTANT NOTE**: These docs are provided as a courtesy but do _NOT_ include the entirety of the OIDC Standard
simply because of its length and complexity.
Please [refer to the standard](https://openid.net/specs/openid-connect-core-1_0.html) for complete details.
Obtain an authorization grant through the OAuth2 protocol. To handle
this request, render a page for the user to confirm the OAuth2 grant
(through e.g. Google). Redirect user to `redirect_uri` with an added
`code` parameter obtained from the authorization provider. A POST will
not render a page for the user; this implementation checks the `confirm`
value in the request.
operationId: authorize_post
responses:
'200':
description: successful operation
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
client_id:
description: 'The client''s ID, issued by authorization server'
type: string
response_type:
description: >-
For an authorization request using the access code flow, the
response type must be "code". If this is missing from the
request then the authorization server must return an error.
type: string
enum:
- code
- token
redirect_uri:
description: Page to redirect to after access has been granted
type: string
confirm:
description: whether to confirm the OAuth2 grant (should be 'yes')
type: string
scope:
description: Requested authorization scope. Must include `openid`. `user` allows getting a user's access information.
type: string
upstream_expires_in:
description: the time (in seconds) during which the upstream refresh token (eg. RAS) is valid. Must be less than the configured maximum. If it's greater, the configured maximum will be used.
type: string
required:
- client_id
- response_type
- redirect_uri
/oauth2/token:
post:
tags:
- oauth2
summary: Exchange code for or refresh the access token.
description: |
**IMPORTANT NOTE**: These docs are provided as a courtesy but do _NOT_ include the entirety of the OIDC Standard
simply because of its length and complexity.
Please [refer to the standard](https://openid.net/specs/openid-connect-core-1_0.html) for complete details.
Exchange the `code` obtained from OAuth2 for an access token, or refresh
the access token using a refresh token.
operationId: token
responses:
'200':
description: successful operation
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
grant_type:
description: >-
Value MUST be one of the supported grant types:
`"authorization_code"` or `"client_credentials"`
type: string
code:
description: >-
(Required if `grant_type` is `"authorization_code"`;
unused otherwise) The authorization code returned from the
OAuth2 authorization request
type: string
redirect_uri:
description: >-
(Required if `grant_type` is `"authorization_code"`;
unused otherwise) Must be identical to the
`"redirect_uri"` included in the original authorization
request
type: string
scope:
description: >-
(Optional if `grant_type` is `"client_credentials"`;
unused otherwise) Requested authorization scope. If
provided, must include `openid`. `user` allows getting a
user's access information.
type: string
client_id:
type: string
required:
- grant_type
/oauth2/revoke:
post:
tags:
- oauth2
summary: Revoke a refresh token per RFC 7009
description: Revoke a refresh (not access) token granted to a user.
operationId: revoke
responses:
'200':
description: 'successful operation, OR invalid token submitted'
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
token:
description: Refresh token that the user wants to revoke
type: string
required:
- token
/login/shib:
get:
tags:
- login
summary: Initiate login via shibboleth provider
description: |
NOTE that this endpoint only exists if shibboleth is enabled as an
identity provider in the fence config. Currently this only happens for
`login.bionimbus.org`.
parameters:
- name: shib_idp
required: false
in: query
description: >-
Identifier for the shibboleth IDP. Available identifiers are what
is listed by the `login.bionimbus.org/Shibboleth.sso/DiscoFeed`
endpoint. If no `shib_idp` is specified, defaults to NIH login.
schema:
type: string
example: 'urn:mace:incommon:uchicago.edu'
responses:
302:
description: redirect to external identity provider
/login/fence:
get:
tags:
- login
summary: Initiate login via Fence provider (multi-tenant Fence)
description: |
NOTE that this endpoint only exists if fence is enabled as an
identity provider in the fence config.
parameters:
- name: idp
required: false
in: query
description: >-
Identifier for the IDP. Specifying `idp=shibboleth` lets us
specify a `shib_idp`. If no `idp` is specified, defaults to
NIH login.
schema:
type: string
example: 'shibboleth'
- name: shib_idp
required: false
in: query
description: >-
Identifier for the shibboleth IDP. Available identifiers are what
is listed by the `login.bionimbus.org/Shibboleth.sso/DiscoFeed`
endpoint. If no `shib_idp` is specified, defaults to NIH login.
schema:
type: string
example: 'urn:mace:incommon:uchicago.edu'
responses:
302:
description: redirect to external identity provider
/jwt/keys:
get:
tags:
- keys
summary: >-
Return the public keys which can be used to validate JWTs issued and
signed by fence
operationId: getKeys
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/PublicKeys'
/user:
get:
tags:
- user
summary: Return info about the current user
description: >-
**IMPORTANT NOTE**: These docs are provided as a courtesy but do _NOT_ include the entirety of the OIDC Standard
simply because of its length and complexity.
Please [refer to the standard](https://openid.net/specs/openid-connect-core-1_0.html) for complete details.
security:
- OAuth2:
- user
operationId: getUserInfo
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
'/admin/user/{username}':
get:
tags:
- 'admin/user'
summary: Return info about a given user
description: Admin method to retrieve info about any given user
parameters:
- name: username
required: true
in: path
description: Username of user to find
schema:
type: string
security:
- OAuth2:
- user
operationId: getUserInfo
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
'404':
description: Couldn't find user
'/admin/user/{username}/soft':
delete:
tags:
- 'admin/user'
summary: Soft-delete user
description: Admin method to soft-delete a user, setting the user to inactive
security:
- OAuth2:
- admin
operationId: softDeleteUser
parameters:
- name: username
required: true
in: path
description: Username of user to deactivate
schema:
type: string
responses:
'204':
description: successful deletion
'404':
description: Couldn't find user
'/admin/user/{username}/reactivate':
post:
tags:
- 'admin/user'
summary: Reactivate a soft-deleted user
description: Admin method to reactivate a soft-deleted user, setting the user back to active
security:
- OAuth2:
- admin
operationId: reactivateUser
parameters:
- name: username
required: true
in: path
description: Username of user to reactivate
schema:
type: string
responses:
200:
description: Successful operation
400:
description: User is already active
/admin/user:
post:
tags:
- admin/user
summary: Add a new user
description: Admin method to add a new user
security:
- OAuth2:
- admin
operationId: createUser
responses:
'200':
description: New user
content:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
requestBody:
$ref: '#/components/requestBodies/NewUser'
/logout:
get:
tags:
- logout
summary: Log out the current user
description: Log out the current user and redirect to the provided url.
The logout will propogate, depending on the identity provider.
parameters:
- in: query
name: next
schema:
type: string
description: The url to redirect the user to after logout
required: false
- in: query
name: force_era_global_logout
schema:
type: boolean
description: Use era commons itrust to logout
required: false
responses:
'302':
description: redirect to root or url in parameter if provided
/data/{file_id}:
delete:
tags:
- data
summary: delete all locations of a stored data file and remove its record from indexd
description: >-
After a user uploads a data file and it is registered in indexd (before
or after it is mapped into the graph via metadata submission), this
endpoint will delete the file from its storage locations (saved in the
record in indexd) and delete the record in indexd.
security:
- OAuth2:
- data
responses:
204:
description: successful operation
500:
description: >-
internal server error; could not delete stored files, or not able to
delete indexd record
content-type: application/json
'/data/download/{file_id}':
get:
tags:
- data
summary: Create a signed URL for data download given a file_id
description: Allow users to get a signed URL for a data file.
security:
- OAuth2:
- user
operationId: downloadSignedURL
parameters:
- name: file_id
required: true
in: path
description: data UUID
schema:
type: string
- name: protocol
required: false
in: query
description: >-
a protocol provided by storage provider, e.g. http, ftp, s3, gs
schema:
type: string
enum:
- http
- s3
- gs
- name: expires_in
required: false
in: query
description: >-
the time (in seconds) in which return url is valid. Must be less
than the configured maximum (default is 3600). If it's greater,
the configured maximum will be used.
schema:
type: integer
- name: redirect
required: false
in: query
description: >-
if set, then a redirect to the signed url will be sent.
Otherwise, json data with the url is returned.
schema:
type: boolean
- name: no_force_sign
required: false
in: query
description: >-
if `no_force_sign=True`, this will
request to *not* sign the resulting URL (i.e. just provide the
public url without using anonymous signing creds).
schema:
type: boolean
- name: userProject
required: false
in: query
description: >-
a Google Project to bill for accessing data in requester pays buckets in Google Storage.
Will override any configured default billing projects. If Fence is configured
to automatically attempt to provide the necessary service account(s) billing permission,
the provided Google Project will need to have given the Fence admin service account
necessary permissions to create custom roles and set Project IAM policies. Please see
README for more information.
schema:
type: string
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/SignedURL'
'400':
description: 'Invalid input: UUID not found or invalid location'
'404':
description: 'No location found for this file'
'/ga4gh/drs/v1/objects/{object_id}/access/{access_id}':
get:
summary: GA4GH DRS Access API to get a URL for fetching bytes.
description: >-
Returns a URL that can be used to fetch the bytes of a DrsObject.
This method only needs to be called when using an AccessMethod that contains an access_id
(e.g., for servers that use signed URLs for fetching object bytes).
operationId: GetAccessURL
responses:
'200':
description: The access URL was found successfully.
content:
'*/*':
schema:
$ref: '#/components/schemas/AccessURL'
'400':
description: The request is malformed.
'401':
description: The request is unauthorized.
'404':
description: The requested access URL wasn't found
'403':
description: The requester is not authorized to perform this action.
'500':
description: An unexpected error occurred.
parameters:
- name: object_id
schema:
type: string
in: path
required: true
description: An id of a DrsObject
- name: access_id
schema:
type: string
in: path
required: true
description: An access_id from the access_methods list of a DrsObject
tags:
- data
post:
summary: GA4GH DRS Access API to get a URL for fetching bytes.
description: >-
Returns a URL that can be used to fetch the bytes of a DrsObject.
This method only needs to be called when using an AccessMethod that contains an access_id
(e.g., for servers that use signed URLs for fetching object bytes).
operationId: PostAccessURL
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RequestUrlPassport'
responses:
'200':
description: The access URL was found successfully.
content:
'*/*':
schema:
$ref: '#/components/schemas/AccessURL'
'400':
description: The request is malformed.
'401':
description: The request is unauthorized.
'404':
description: The requested access URL wasn't found
'403':
description: The requester is not authorized to perform this action.
'500':
description: An unexpected error occurred.
parameters:
- name: object_id
schema:
type: string
in: path
required: true
description: An id of a DrsObject
- name: access_id
schema:
type: string
in: path
required: true
description: An access_id from the access_methods list of a DrsObject
tags:
- data
'/data/upload':
post:
tags:
- data
summary: >-
Create a new blank record in indexd to use for uploading a data file
less than 5GB. For files larger than 5GB, please use multipart upload presigned url
description: |
This is the first step on the API side for the data upload flow. This
endpoint causes fence to make a request to indexd to create a new, blank
index record, and returns the GUID for this new record and a presigned
URL which a client can then use to upload their data file directly to a
storage bucket. No parameters are accepted because fence retrieves the
username from the current token to send to indexd for the `uploader`
field in the new record.
This API also supports utilizing the newer authorization within the indexing
service by providing an "authz" field.
If an "authz" field is provided, the authorization checks are slightly different:
your user must have *both* "create" and "write-storage" permission on the resources
you are including in the "authz" list.
In addition to a different authorization check, when "authz" is provided the
"uploader" field in indexd with *not* be populated.
Previous authorization check requires a more general, global upload permission:
"file_upload" on "/data_file" resource. When "authz" is *not* provided, this
endpoint will check for that permission for your user.
Accepts a "guid" field in the request body. If "guid" is provided, it checks indexd for an existing record. If not found, it raises a 404.
security:
- OAuth2:
- user
- data
operationId: uploadBlank
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RequestUploadBlank'
responses:
201:
description: successful operation; created new record in indexd
content:
application/json:
schema:
type: object
properties:
guid:
type: string
description: >-
the GUID from the newly created record in indexd
url:
type: string
description: the presigned URL usable for data upload
404:
description: Record with <guid> not found.
'/data/upload/{file_id}':
get:
tags:
- data
summary: Create a signed URL for data upload specified by file_id
description: >-
Allow users to get a signed URL to upload data given the location of
preference.
security:
- OAuth2:
- user
operationId: uploadSignedURL
parameters:
- name: file_id
required: true
in: path
description: data UUID
schema:
type: string
- name: protocol
required: false
in: query
description: >-
a protocol provided by storage provider, e.g. http, ftp, s3, gs
schema:
type: string
enum:
- http
- s3
- name: expires_in
required: false
in: query
description: >-
the time (in seconds) in which return url is valid. Must be less
than the configured maximum (default is 3600). If it's greater,
the configured maximum will be used.
schema:
type: integer
- name: file_name
required: false
in: query
description: >-
the requested file name in the cloud bucket you will upload to.
If not provided, will use the GUID/file_id
schema:
type: string
- name: bucket
required: false
in: query
description: >-
the requested bucket to upload to.
If not provided, defaults to the configured DATA_UPLOAD_BUCKET.
schema:
type: string
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/SignedURL'
'400':
description: 'Invalid input: UUID not found or invalid location'
'/multipart/init':
post:
tags:
- data
summary: >-
Initilize a multipart upload for AWS bucket. It returns an uploadId which
can be used for uploading object parts (see /multipart/upload) and completing
the upload (see /multipart/complete)
description: >-
For uploading the big file with the size is larger than 5GB in data upload
flow, Fence needs to provide a list of endpoints for supporting multipart upload presigned url
This is the first step on the API side for the multipart upload presigned url. This endpoint
causes fence to make a request to indexd to create a new, blank index record, and returns
the GUID for this new record and an uploadId for multipart upload presigned url.
Accepts a "guid" field in the request body. If "guid" is provided, it checks indexd for an existing record. If not found, it raises a 404.
security:
- OAuth2:
- user
- data
operationId: multipartUploadInit
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/InitMultipartUpload'
responses:
201:
description: successful operation; created new blank record in indexd and uploadId for multipart upload
content:
application/json:
schema:
type: object
properties:
guid:
type: string
description: >-
the GUID from the newly created record in indexd
uploadId:
type: string
description: the uploadId for multipart upload presigned URL usable for data upload
404:
description: Record with <guid> not found.
'/multipart/upload':
post:
tags:
- data
summary: >-
Upload an object part given uploadId
description: >-
This is the second step on the API side for the multipart upload presigned url. The object is chopped into
multiple parts with part number start from 1. Each part is submitted to the cloud resource with this
endpoint by providing the part number a long with uploadId. It is worth to mention that the minimal supported
part size is 5 MB as describe in https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html
security:
- OAuth2:
- user
- data
operationId: multipartUpload
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RequestMultipartUpload'
responses:
200:
description: successful operation
content:
application/json:
schema:
type: object
properties:
presigned_url:
type: string
description: the presigned URL for uploading part
'/multipart/complete':
post:
tags:
- data
summary: >-
Complete aws multipart upload
description: >-
This is the last step for the multipart upload presigned url. All the parts which were submitted
need to be combined together. This enpoint takes a list of the part info (partNumber, Etag)
and uploadId in order to finish the upload
security:
- OAuth2:
- user
- data
operationId: multipartUploadComplete
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CompleteMultipartUpload'
responses:
200:
description: successful operation
'/data/buckets':
get:
tags:
- data
summary: >-
Get list of buckets and relevant bucket info
description: >-
Returns a list of buckets and relevant bucket information provided in the fence-config under AWS_BUCKETS and GS_BUCKETS.
It filters out sensitive information about the bucket and only shows information like bucket region.
operationId: getBuckets
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/BucketInfo'
/credentials:
get:
tags:
- credentials
summary: List credential resources
description: List different resources user can have credentials
security:
- OAuth2:
- us
# --- truncated at 32 KB (91 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/university-of-chicago/refs/heads/main/openapi/university-of-chicago-fence.yaml