Product | Greenhouse integration |
Expert(s) | everyone |
Slack channel | none |
This article was last verified on | 03/19/2024 |
🔍 Articles in This Section
Please use the following list to see additional internal articles regarding the Greenhouse integration:
- (Internal) Greenhouse Integration Overview
- (Internal) Greenhouse Integration Customer Eligibility and Setup
- Greenhouse Integration User Permissions (📍you are here)
- Greenhouse Integration Available Features, Sync Timings, and FAQ
Greenhouse permissions are somewhat complicated, but our approach to them in Gem is fairly straightforward. This article covers three things:
- How we model Greenhouse permissions in Gem. Because the Harvest API doesn’t provide all the info we need to fully model Greenhouse permissions, this is actually pretty simple.
- Where we’ve actively deviated from Greenhouse permissions. For example in Talent Compass we show some things that aren’t visible to Greenhouse users.
- How Greenhouse permissions actually work in Greenhouse - sort of. The Greenhouse help center and Greenhouse itself are the best places to look for this, so we’ll mostly just link to those.
How we model GH permissions in Gem
Below are the DB fields we use to model GH permissions, and their intended usage in the Gem product. Note that we may choose to ignore some of these permissions in parts of the product, like Pipeline Analytics.
Fields we populate from the API
These are synced automatically from the Harvest API as part of deep sync.
GreenhouseUser.site_admin
Determines which users are GH admins
GreenhouseUser
site_admin [Boolean]- In Gem, site admins can see all GH data, including candidate details and scorecards for apps on all jobs (including confidential jobs) → This statement is possibly incorrect
- We don’t allow admins to see private candidates unless they are a Greenhouse site admin with permission to create/view private candidates. Then, Support or Customer Success can file a task to have this updated. Example task.
GreenhouseUserPermission
Determines which non-admin users can see which jobs and their apps
GreenhouseUserPermission
job_id (GreenhouseJob)user_id (GreenhouseUser)role_id (GreenhouseUserRole)- A user permission row gives a particular GH user access to a specific GH Job.
- When a user can see a GH job in Gem, they can also see all applications on that job and all details of those applications (candidate info and scorecards)
- The “role_id” links to a GreenhouseUserRole and would theoretically give us details on the User’s level of access to the Job, but Harvest API only gives us the name and the “type” of each role, and in practice almost every role we sync is of type “job admin”. So, these are not useful on their own.
Fields we populate manually(ifat all)
These are permissions settings that are not available from the Harvest API. Nonetheless, they affect our GH integration - to the point where our customers have asked us to respect them in the product. They’re populated by us running scripts manually when customers request them.
GreenhouseRolePermission
A manually populated hack to model more granular GH job permissions for non-admins. As of April 2022, this table has 12 rows.
GreenhouseRolePermission
role_greenhouse_id (GreenhouseUserRole)can_view_private_candidatescan_see_private_notes_and_info- Rows in this table are set manually with the script set_greenhouse_role_permissions.py
Team and User settings
- can_users_view_jobless_gh_prospects is set for 6 teams as of Apr 2022
- can_view_private_gh_candidates_as_site_admin is set for 56 users as of Apr 2022
Team
can_users_view_jobless_gh_prospects [Boolean]
User
can_view_private_gh_candidates_as_site_admin [Boolean]- These are set with the scripts set_team_greenhouse_permissions.py and set_user_greenhouse_permissions.py respectively
- Without the team setting, Prospects with no job set are not visible to regular GH users
- Without the user setting, if a user is a GH Site Admin they still aren’t allowed to see private GH candidates in Gem
Where we’ve actively deviated from GH permissions
Talent Compass
- Every GH user can see all applications on non-confidentialjobs (we ignore GreenhouseUserPermission)
- restricted viewing applications anywhere in Gem if the job is confidential
- PA - redact job names + candidate details do not show candidates when you click on the counts
- Rest of the product’s job + candidate visibility is unaffected.
- Why? We think GH, as an ATS, takes an approach of “only give access to users who need it”, and specifically wants to lock down scorecards and offer details. Talent Compass exposes neither scorecards nor offer details, so we think we can be more permissive. Also, the stats would be much less useful they were only for roles that you’re an interviewer on or directly involved in.
- use_strict_gh_permissions_in_pa to revert back to OG greenhouse permissions, we can set this for the team with
- Setting this for a team will result in:
- Every GH user can see applications from private candidateson non-confidential jobs (we don’t require the special manual setting in GreenhouseRolePermission or for site admins in User.can_view_private_gh_candidates_as_site_admin)
- GH’s API does tell us that their role is site admin, but there is an additional setting for whether site admins can see private candidates on a confidential job when they’re not a job admin for that job. The API doesn’t tell us the latter, so we need to make the update manually.
- Why? Private candidates in GH are almost exclusively hired candidates. There’s a setting to make candidates private when marking them as hired that’s often defaulted to “yes”. In Talent Compass, a lot of the analytics are specifically about hired candidates, so it’s important that we show them. Also, based on the note box in the GH article about private candidates, GH also includes private candidates in reports run by any user.
- Caveat: if a user’s GH account is marked disabled, they will not be able to see any potentially private or confidential data. This overrides the above.
Search
- All Gem users can see all candidates except for:
- Those that have been hired by the company.
- Those that are marked as private candidates.
- TODO: add more details here on:
- whether we filter based on applications that the user doesn’t have ATS access to
- Whether we show app info, scorecards, etc for apps that the user doesn’t have ATS access to
- I think we don’t show either of these, so we’re really using the TP / standard GH permission model here
Talent Pipeline
We follow the settings in GreenhouseUserPermission. I believe this should be populated directly from Greenhouse. This is done through gh_get_visible_app_ids_set_for_user in greenhouse_permissions, with allow_hired_candidates=False and allow_all_nonconfidential_jobs=False. For private candidates, there is an override setting for Gem users marked as site_admin in Greenhouse with users.can_view_private_gh_candidates_as_site_admin=True.
How GH permissions actually work
Notable behaviors
- (record any notable GH permission behaviors here!)
Useful links
- Permission policies overview
- User permissions grid
- Basic user-specific permissions
- Job Admin user-specific permissions
- Site Admin user-specific permissions
- Job Admin levels and permissions
- What can a Job Admin: Standard do?
- Why am I unable to view private or hired candidates?
- I am a Site Admin. Why am I unable to access certain candidates or data?
- Why am I unable to search for or view some candidates?
How to find out more
- Check out the GH help center or just google “greenhouse
- Look at the actual permission settings on the recommendfm.com Greenhouse instance, and see how they work for different users on that team.
- Ask our recruiting team, or the rec ops person at a customer using GH - they’re usually pretty familiar with the details of how GH works!
” to get specific GH permissions questions answered - their help center articles are useful
Fancy table
From User permissions grid, copied Apr 2022:
Task | Basic | Job Admin: Standard | Job Admin: Private | Job Admin: Custom | Site Admin |
Submit candidate referrals for open jobs | X | X | X | X | X |
Post open jobs to social media and schedule recurring social posts on their personal social pages | X | X | X | X | X |
View candidates, access interview kits, and submit scorecards for jobs they are active on | X | X | X | X | |
View Job Setup, including the Scorecard, Interview Plan, Interview Kits, and Job Info, for jobs they’re active on | X | X | X | X | |
View job dashboards and work with Pipeline Tasks for jobs they’re active on | X | X | X | X | |
View Private tab and Offer Details tab on candidate profile, and see all private Job Info fields for jobs they’re active on | Configurable | Configurable | User-Specific Permission | ||
Advance, reject, and email candidates and prospects | X | Configurable | Configurable | X | |
Manually merge duplicate candidates | Configurable | Configurable | Configurable | X | |
Edit Job Setup, including Scorecards, Interview Plans, and Job Posts for jobs they’re active on | Configurable | Configurable | Configurable | X | |
Create and view profiles of Private candidates and prospects | Configurable | Configurable | Configurable | User-Specific Permission | |
Add and remove users to jobs they’re active on | Configurable | Configurable | Configurable | X | |
• Can create new jobs and request job approvals
• Manage custom fields
• Manage company metadata
• Manage company email and social templates | User-Specific Permission | User-Specific Permission | User-Specific Permission | X | |
View and edit permission policies page | X | ||||
• Edit other users’ advanced permissions
• Create and override default approval flows
• See EEOC reports
• Create and view Private candidates
• Bulk edit jobs | User-Specific Permission | ||||
Manage prospects on no jobs | User-Specific Permission | User-Specific Permission | User-Specific Permission | User-Specific Permission |
From Branko on the Extension
Did a quick audit of the GH integration to see how we’re respecting confidential jobs. Specifically took a look at the job, potential duplicates, and candidate info queries as those expose jobs (either directly or indirectly through the candidate’s applications).
- candidate info (api_greenhouse_candidate): We query the harvest API to get the candidate with the same gh id. We use get_permissioned_candidates to check if user can see at least one of the candidate’s applications.
- HOWEVER, once we check that the user has permission to see the candidate, it doesn’t look like we filter out non-permissive job apps on the candidate. After the candidate check, we just return GreenhouseInfoCandidate.from_api_object(gh_candidate) which could leak private apps on the candidate
- E.g candidate C with apps for jobs X, Y; user has access to X; we could leak Y to the user via C’s applications
- duplicates query (potential_greenhouse_duplicates): Using deep sync tables (ATSEmailToCandidate) or the harvest API, we query for candidates with email or name match (name match just for deep-sync). Then we check if user can view each candidate by checking if user can see at least one of the candidate’s applications (using load_candidates_for_user or get_permissioned_candidates).
- For the deep sync path, we do filter out non-permissive job apps from the candidate (load_candidates_for_user does this).
- For the harvest api path, it looks like we DO NOT filter out private apps
- jobs (public_api_greenhouse_jobs)[this is used in the Jobs dropdown typeahead]: Using deep sync tables we query for all open jobs the user has access to using get_visible_jobs_for_user_query(which checks permissions using the GreenhouseUserPermission table). If the team doesn’t have deep sync, we use the Partner API with the user’s access token to get all the jobs. This data should respect confidentiality as it’s coming from a gh endpoint with user based auth
- This endpoint looks good, nothing worrisome stood out to me
From Rachel on Activity Feed
In our current approach, any candidate in the GH instance is fair game to have a Gem profile. I think on the profile we still respect GH permissions for which applications a user can see, but we don’t have any limitations to prevent a user from seeing that a candidate is in Gem even if they can’t see the associated (confidential) applications.
If we maintain 2 Gem instances and for the non-exec one we filter during deep syncs to prevent adding confidential exec candidates, then we won’t import these candidates / surface them in candidate rediscovery incorrectly. That said, I think other things could go wrong if for example a single CK user has a Gem account on both instances, since emails sent for a conf. job could end up reflected on the same candidate’s profile in the other Gem instance.
Finally, we probably also need to check with the sourcing folks on whether the extension handles gh permissions today — I know they did a rewrite that now hits the GH API directly rather than using our deep sync tables, which could cause problems if it isn’t handling user permissions as well.
- How we model GH permissions in Gem
- Fields we populate from the API
- Fields we populate manually(ifat all)
- Where we’ve actively deviated from GH permissions
- Talent Compass
- Search
- Talent Pipeline
- How GH permissions actually work
- Notable behaviors
- Useful links
- How to find out more
- Fancy table
- From Branko on the Extension
- From Rachel on Activity Feed