New guide: Discovering resources for a user

Is your application taking advantage of the recommended workflow for discovering a user's repositories and organizations? With the recent improvements to the API, the process is simpler than ever. In our newest guide, we show you how to reliably identify the resources that your app can access for a given user.

If you have any questions or feedback, we'd love to hear from you.

Prepare for upcoming organization permissions changes

UPDATE (2015-06-10): As announced on June 10, these changes will become an official part of GitHub API v3 on June 24. (This post originally announced that these changes would come to GitHub API v3 on February 24.)

Last month, we released a preview of several API changes related to managing organization members and repositories. Today, we're finalizing these changes. This new functionality is now stable and suitable for production use. If your application relies on any of the affected functionality (described below), be sure to update your code before June 24 to account for these changes.

Breaking changes coming on June 24

If your application uses any of the following APIs, then you are affected by this change:

  • APIs for managing your organization's admins through the Owners team
  • The List your repositories API
  • The [List your organizations][list-your-organizations] API
  • The [List user organizations][list-user-organizations] API

If your application uses these APIs, we urge you to update your application as soon as possible. (Read last month's announcement for more details on the changes.)

Starting today, we're offering a migration period allowing applications to opt in to these changes (as described below). On June 24, these changes will become official parts of the GitHub API v3. At that time, these changes will apply to all API consumers.

Migration period

During the migration period, you can opt-in to these changes using the following custom media type in the Accept header:

application/vnd.github.moondragon+json

We want to make these updates as smooth as possible for everyone, and we hope that the migration period gives you flexibility to adopt these changes on your own schedule. If you have any questions or feedback, please [get in touch with us][contact]!

[list-user-organizations]: /v3/orgs/#list-organizations-for-a-user[list-your-organizations]: /v3/orgs/#list-organizations-for-the-authenticated-user[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API

Replace older SSH keys created by your application

Back in February, we improved the security audit trail for SSH keys. Soon, organizations will be able to block access for SSH keys that were created prior to those improvements. If your application relies on deploy keys or user keys for repository access, we recommend replacing any keys created before February 24, 2014.

To ensure that your application is not affected by organizations blocking access to these keys, you should replace the affected keys by January 15, 2015.

How should you replace these keys?

We recommend the following steps for identifying and replacing the affected keys.

1. Identify the affected keys

You only need to replace keys that your application created prior to February 24, 2014. If you don't know when your app created a given key, you can get the creation timestamp from the API. The created_at property is available for deploy keys and for user keys.

2. Inform the affected users

Once you know which keys you need to replace, we recommend that you inform the affected users.

For security, GitHub automatically sends an email to a user whenever a new SSH key is added to their account. Similarly, when a new deploy key is added to a repository, GitHub sends an email to the repository's administrators. When you replace your application's old keys with new ones, GitHub will email the affected users. To avoid surprising those users, you should alert them that you'll be replacing your keys. You may want to include a link to this post in your message.

3. Add a new key

Use the API to add the new deploy key or user key.

4. Delete the old key

Once your application is using the new key, use the API to delete the old one. There's an API for deleting deploy keys and an API for deleting user keys.

We're here to help

As always, if you have any questions or concerns, please get in touch.

New Attributes for Starring API

You can now see when a user starred a repository. To receive the new response format containing the starred_at field, request the new media type:

curl -H "Accept: application/vnd.github.v3.star+json" https://api.github.com/users/andrew/starred

Note the starred repository is now available in the repo field.

Feedback

If you have any questions or feedback about these changes, please drop us a line.

Preview the upcoming organization permission changes

UPDATE (2014-12-12): The [List your organizations][list-your-organizations] API is now included in this preview as well.

We have some upcoming changes that will affect the way organization members and repositories are managed. The most important changes are:

  • The Owners team will no longer be special.
  • The List your repositories API will include organization-owned repositories.
  • The [List user organizations][list-user-organizations] API will only include public organization memberships.
  • The [List your organizations][list-your-organizations] API will require user scope or read:org scope.

What's happening to the Owners team?

Currently, members of your Owners team are administrators of your organization. Soon, your Owners team will become a totally normal team. Adding and removing Owners team members won't change their administrator status anymore. Instead, you'll be able to directly grant admin permissions to your organization's members without adding them to any special teams.

We won't delete your Owners team, but you'll be able to delete or rename it yourself if you want. Organizations created after the change won't have an Owners team.

What should you do?

In preparation for this change to the Owners team, we're releasing a few new APIs. You'll be able to use these APIs to manage organization admins without relying on the Owners team.

Adding an organization admin

To add a new organization admin, use the new [Add or update organization membership][add-org-membership] endpoint, specifying a role of "admin" in the request body. This replaces adding or inviting people to the Owners team.

Removing an organization admin

To remove someone from the organization role but keep them as a member of their teams, use the new [Add or update organization membership][add-org-membership] endpoint, specifying a role of "member" in the request body. This replaces removing people from the Owners team.

Listing organization admins

To get a list of all your organization's admins, use the [Organization members list][list-org-members] endpoint, specifying a role of "admin" in the query string. This replaces listing the members of the Owners team.

Checking if someone is an organization admin

To check if a given user is an organization admin, use the new [Get organization membership][get-org-membership] endpoint. If the returned "role" attribute is set to "admin" and the returned "state" attribute is set to "active", the user is an organization admin. This replaces checking if a user is on the Owners team.

What's happening to the "List your repositories" API?

Currently, the List your repositories API only returns repositories that are owned by users, not by organizations. If you want a list of all the repositories that the authenticated user has access to, you need to use multiple API methods.

Soon, this API will include all repositories that the authenticated user has access to (whether they're owned by a user or by an organization).

What should you do?

Many apps use the List your repositories API in conjunction with the [List your organizations][list-your-orgs] and [List organization repositories][list-org-repos] APIs to build up a list of all the repositories the authenticated user has access to. If your app is doing this, you'll be able to get rid of all the organization-related API calls and just use the List your repositories API.

If your app uses the List your repositories API for another purpose, you'll need to update your app to handle the new organization-owned repositories we'll be returning.

What's happening to the "List user organizations" API?

The [List user organizations][list-user-organizations] API is intended provide [public organization memberships][public-org-membership] for any user. When you use this API to fetch your own organizations, this API currently returns your public and private organization memberships.

Soon, this API will only return public organization memberships.

What should you do?

If your app uses the [List user organizations][list-user-organizations] API to fetch all of the organization memberships (public and private) for the authenticated user, you'll need to update your app to use the [List your organizations][list-your-organizations] API instead. The [List your organizations][list-your-organizations] API returns all organizations (public and private) that your app is authorized to access.

What's happening to the "List your organizations" API?

OAuth requests will soon require minimum scopes in order to access the [List your organizations][list-your-organizations] API.

Currently, the API response always includes your [public organization memberships][public-org-membership], regardless of the OAuth scopes associated with your request. If you have user, read:org, write:org, or admin:org scope, the response also includes your private organization memberships.

Soon, this API will only return organizations that your authorization allows you to operate on in some way (e.g., you can list teams with read:org scope, you can publicize your organization membership with user scope, etc.). Therefore, this API will require at least user or read:org scope. (write:org and admin:org scope implicitly include read:org scope.) OAuth requests with insufficient scope will receive a 403 Forbidden response.

What should you do?

If you authenticate via username and password, you are not affected by this change.

If your app only needs to fetch the user's public organization memberships, you should use the [List user organizations][list-user-organizations] API instead. Since that API only returns public information, it does not require any scopes.

Preview period

Starting today, these new APIs are available for developers to preview. We expect the preview period to last for four weeks. (Stay tuned to the developer blog for updates.) At the end of the preview period, these additions will become official components of the GitHub API.

While these additions are in their preview period, you'll need to provide the following custom media type in the Accept header:

application/vnd.github.moondragon-preview+json

During the preview period, we may change aspects of these endpoints. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.

Migration period

At the end of the preview period, we will announce the start of a migration period. At that time, developers should update their applications to use the new APIs for managing organization admins. During this period, you will still be able to use the Owners team to manage your organization's admins, so that you have time to update your applications to use the new APIs without breakage. We expect the migration period to last for four weeks.

At the end of the migration period, the Owners team will no longer be special, and you'll no longer be able to rely on it for managing organization admins.

If you have any questions or feedback, please get in touch with us!

[list-your-orgs]: /v3/orgs/#list-organizations-for-the-authenticated-user[list-org-repos]: /v3/repos/#list-organization-repositories [add-org-membership]: /v3/orgs/members/#set-organization-membership-for-a-user[list-org-members]: /v3/orgs/members/#list-organization-members[get-org-membership]: /v3/orgs/members/#get-organization-membership-for-a-user[list-user-organizations]: /v3/orgs/#list-organizations-for-a-user[list-your-organizations]: /v3/orgs/#list-organizations-for-the-authenticated-user[public-org-membership]: https://help.github.com/articles/publicizing-or-concealing-organization-membership

Removing token attribute from Authorizations API responses

Since OAuth access tokens function like passwords, they should be treated with care. Today we are making it easier to more securely work with authorizations via the Authorizations API. We are deprecating the use of the token attribute in the majority of the Authorizations API responses. For the affected APIs, the token attribute will soon return an empty string. To get ready for that change, we are giving developers a chance to preview the updated API starting today.

What's changing?

The current OAuth Authorizations API requires GitHub to store the full value for each OAuth token on our servers. In order to increase the security for our users, we are changing our architecture to store the SHA-256 digest of OAuth tokens instead. GitHub securely hashes user passwords using bcrypt and we want to provide comparable security for OAuth tokens as well.

Rest assured that this change is an entirely proactive measure from GitHub and is not associated with any security incident.

Who is affected?

This change affects any code that relies on accessing the token attribute from these OAuth Authorizations API responses. For example, our own GitHub for Mac and GitHub for Windows applications relied on reading the token from the Get-or-create an authorization for a specific app API, in order to support multiple installations of our desktop application for a single user.

What should you do?

In order to reduce the impact of removing the token attribute, the OAuth Authorizations API has added a new request attribute (fingerprint), added three new response attributes (token_last_eight, hashed_token, and fingerprint), and added one new API. While these new APIs and attributes do not replace the full functionality that previously existed, they can be used in place of token for most common use cases.

  • token_last_eight returns the last eight characters of the associated OAuth token. As an example, token_last_eight could be used to display a list of partial token values to help a user manage their OAuth tokens.

  • hashed_token is the base64 of the SHA-256 digest of the token. hashed_token could be used to programmatically validate that a given token matches an authorization returned by the API.

  • fingerprint is a new optional request parameter that allows an OAuth application to create multiple authorizations for a single user. fingerprint should be a string that distinguishes the new authorization from others for the same client ID and user.

    For example, to differentiate installations of a desktop application across multiple devices you might set fingerprint to SHA256_HEXDIGEST("GitHub for Mac - MAC_ADDRESS_OF_MACHINE"). Since fingerprint is not meant to be a user-facing value, you should still set the note attribute to help a user differentiate between authorizations on their OAuth applications listing on GitHub.

  • Get-or-create an authorization for a specific app and fingerprint is a new API that is analogous to the Get-or-create an authorization for a specific app API, but adds support for the new fingerprint request parameter.

Preview period

We are making the new Authorizations API available today for developers to preview. During this period, we may change aspects of these endpoints. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.

While these new APIs are in their preview period, you’ll need to provide the following custom media type in the Accept header:

application/vnd.github.mirage-preview+json

We expect the preview period to last 4-6 weeks. (Stay tuned to the developer blog for updates.) At the end of the preview period, these changes will become an official and stable part of GitHub API.

Migration period

At the end of the preview period, we will announce the start of a migration period. Developers will have 8 weeks to update existing code to use the new APIs.

Why SHA-256 over bcrypt?

Some users may be curious why we are not using bcrypt to hash our OAuth tokens like we do for user passwords. Bcrypt is purposefully computationally expensive in order to mitigate brute force attacks against low entropy passwords. However, OAuth tokens are highly random and are not susceptible to brute force attacks. Given that OAuth token validation occurs for each request to the API we chose SHA-256 for performance reasons.

If you have any questions or feedback, please drop us a line.

Preview the New Organization Webhooks API

Today we're very excited to announce Organization Webhooks. Organization Webhooks allow you to subscribe to events that happen across an entire organization.

In addition to being able to subscribe to the existing repository oriented events across an organization, we're also adding some new events which are exclusive to organization webhooks. The new repository event allows you to receive webhook payloads when a new repository is created. By subscribing to the membership event, you'll be notified whenever a user is added or removed from a team.

We’re making this new API for Organization Webhooks available today for developers to preview. The preview period will allow us to get your feedback before declaring the Organization Webhooks API final. We expect the preview period to last for roughly 30-60 days.

As we discover opportunities to improve the API during the preview period, we may ship changes that break clients using the preview version of the API. We want to iterate quickly. To do so, we will announce any changes here (on the developer blog), but we will not provide any advance notice.

At the end of preview period, the Organization Webhooks API will become an official component of GitHub API v3. At that point, the new Organization Webhooks API will be stable and suitable for production use.

We hope you’ll take it for a spin and send us your feedback.

The Deployments API is official

  • November 25, 2014
  • Avatar for atmos atmos

We're happy to announce that the Deployments API is officially part of GitHub API v3. We now consider it stable for production use.

Thanks to everyone who provided feedback during the preview period. We got some great feedback, and hope this feature helps you build the tools you need to make GitHub the best place to ship exactly the way you want.

Preview media type no longer needed

If you used the Deployments API during the preview period, you needed to provide a custom media type in the Accept header:

application/vnd.github.cannonball-preview+json

Now that the preview period has ended, you no longer need to pass this custom media type.

Instead, we recommend that you specify v3 as the version in the Accept header:

application/vnd.github.v3+json

Feedback

We'll never be done listening to you! As always, please don't hesitate to share your feedback.

Status API Limits

To ensure a high level of service for all API consumers, we will soon limit the number of statuses to 1000 per commit SHA, repository, and context.

Beginning Monday, November 3rd, we will trim existing data sets that exceed this limit, deleting the oldest records first. Attempts to create statuses beyond that limit will result in a validation error.

If you have any feedback or questions, please don't hesitate to contact us.

Deployment webhook payload changes

On November 4th, 2014, we will begin sending a new format for deployment and deployment status payloads for webhooks. In the meantime we'll be running in a compatibility mode that will give integrators the time needed to start taking advantage of the new format. Integrators who are working with webhooks and deployments are advised to upgrade to the new payload format to avoid service interruption.

This change brings the payloads for these events more inline with the responses you'd receive from the API. Instead of having deployment and deployment status attributes as top-level keys, we will now nest them under deployment and deployment_status keys. Since we're still in the preview period for the deployments API we felt it was best to correct this inconsistency now.

DeploymentEvent Changes

Old Format

{
  "id": 42,
  "sha": "deadbeef",
  "ref": "master",
  "task": "deploy",
  "name": "my-org/our-app",
  "environment": "production",
  "payload": {},
  "description": "Deploying master",
  "repository": {},
  "sender": {}
}

Current Format - 2014/10/22

{
  "id": 42,
  "sha": "deadbeef",
  "ref": "master",
  "task": "deploy",
  "name": "my-org/our-app",
  "environment": "production",
  "payload": {},
  "description": "Deploying master",
  "repository": {},
  "deployment": {
    "url": "https://api.github.com/repos/my-org/our-app/deployments/42",
    "id": 42,
    "sha": "deadbeef",
    "ref": "master",
    "task": "deploy",
    "environment": "production",
    "payload": {},
    "description": "Deploying master",
    "creator": {},
    "created_at": "2014-09-23T16:37:49Z",
    "updated_at": "2014-09-23T16:37:49Z",
    "statuses_url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses"
  },
  "sender": {}
}

New Format - 2014/11/05

{
  "deployment": {
    "url": "https://api.github.com/repos/my-org/our-app/deployments/42",
    "id": 42,
    "sha": "deadbeef",
    "ref": "master",
    "task": "deploy",
    "environment": "production",
    "payload": {},
    "description": "Deploying master",
    "creator": {},
    "created_at": "2014-09-23T16:37:49Z",
    "updated_at": "2014-09-23T16:37:49Z",
    "statuses_url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses"
  },
  "repository": {},
  "sender": {}
}

DeploymentStatusEvent Changes

Old Format

{
  "id": 2600,
  "state": "success",
  "deployment": {},
  "target_url": "https://gist.github.com/deadbeef",
  "description": "Deployment was successful",
  "repository": {},
  "sender": {}
}

Current Format - 2014/10/22

{
  "id": 2600,
  "state": "success",
  "target_url": "https://gist.github.com/deadbeef",
  "description": "Deployment was successful",
  "repository": {},
  "deployment_status": {
    "url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses2600",
    "id": 2600,
    "state": "success",
    "creator": {},
    "target_url": "https://gist.github.com/deadbeef",
    "description": "Deployment was successful",
    "created_at": "2014-09-23T16:45:49Z",
    "updated_at": "2014-09-23T16:45:49Z",
    "deployment_url": "https://api.github.com/repos/my-org/our-app/deployments/42",
    "repository_url": "https://api.github.com/repos/my-org/our-app"
  },
  "deployment": {},
  "sender": {}
}

New Format - 2014/11/05

{
  "deployment_status": {
    "url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses2600",
    "id": 2600,
    "state": "success",
    "creator": {},
    "target_url": "https://gist.github.com/deadbeef",
    "description": "Deployment was successful",
    "created_at": "2014-09-23T16:45:49Z",
    "updated_at": "2014-09-23T16:45:49Z",
    "deployment_url": "https://api.github.com/repos/my-org/our-app/deployments/42",
    "repository_url": "https://api.github.com/repos/my-org/our-app"
  },
  "deployment": {},
  "repository": {},
  "sender": {}
}

If you have any questions or feedback, please get in touch.