Gen3 Data Commons APIs (CTDS)

Open-source data platform maintained by the University of Chicago Center for Translational Data Science. Gen3 auto-generates FAIR APIs (data submission, GraphQL/Peregrine query, indexing/Indexd, Fence auth) for building and accessing biomedical data commons. Code is fully public under Apache 2.0 across the uc-cdis GitHub organization.

OpenAPI Specification

university-of-chicago-fence.yaml Raw ↑
---
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