mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
feat: show required permissions in mgmt api docs (#41151)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Show required FGA permissions for each route in the management API docs. Permissions are pulled from the `fga_permissions` security field in the OpenAPI spec. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * API reference docs now extract and display fine-grained access-control permissions per endpoint. When present, a dedicated block lists required permissions with a clear header explaining the token requirements. * The permissions block appears alongside existing OAuth scope information and only shows for endpoints that declare such permissions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Chris Chinchilla <chris.ward@supabase.io>
This commit is contained in:
1 parent
3a391d4f6b
commit
e96efe695f
2 files changed
+29
-9
No files matched your search
@@ -118,7 +118,7 @@ interface IApiFormUrlEncodedDTO {
|
||||
}
|
||||
}
|
||||
|
||||
type ISecurityOption = IBearerSecurity | IOAuth2Security
|
||||
type ISecurityOption = IBearerSecurity | IOAuth2Security | IFgaSecurity
|
||||
|
||||
interface IBearerSecurity {
|
||||
bearer: []
|
||||
@@ -128,6 +128,10 @@ interface IOAuth2Security {
|
||||
oauth2: Array<'read' | 'write'>
|
||||
}
|
||||
|
||||
interface IFgaSecurity {
|
||||
fga_permissions: string[]
|
||||
}
|
||||
|
||||
export function getTypeDisplayFromSchema(schema: ISchema) {
|
||||
if ('allOf' in schema) {
|
||||
if (schema.allOf.length === 1) {
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { isFeatureEnabled } from 'common'
|
||||
import { Fragment } from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import {
|
||||
Badge,
|
||||
cn,
|
||||
Tabs_Shadcn_,
|
||||
TabsContent_Shadcn_,
|
||||
TabsList_Shadcn_,
|
||||
TabsTrigger_Shadcn_,
|
||||
Tabs_Shadcn_,
|
||||
cn,
|
||||
} from 'ui'
|
||||
|
||||
import { isFeatureEnabled } from 'common'
|
||||
import { type IApiEndPoint } from './Reference.api.utils'
|
||||
import { RefInternalLink } from './Reference.navigation.client'
|
||||
import { ApiOperationBodySchemeSelector } from './Reference.ui.client'
|
||||
import ApiSchema from '~/components/ApiSchema'
|
||||
import { clientSdkIds, REFERENCES } from '~/content/navigation.references'
|
||||
import { REFERENCES, clientSdkIds } from '~/content/navigation.references'
|
||||
import {
|
||||
getApiEndpointById,
|
||||
getCliSpec,
|
||||
@@ -20,7 +23,7 @@ import {
|
||||
getSelfHostedApiEndpointById,
|
||||
getTypeSpec,
|
||||
} from '~/features/docs/Reference.generated.singleton'
|
||||
import { getRefMarkdown, MDXRemoteRefs } from '~/features/docs/Reference.mdx'
|
||||
import { MDXRemoteRefs, getRefMarkdown } from '~/features/docs/Reference.mdx'
|
||||
import type { MethodTypes } from '~/features/docs/Reference.typeSpec'
|
||||
import { formatMethodSignature } from '~/features/docs/Reference.typeSpec'
|
||||
import {
|
||||
@@ -35,9 +38,6 @@ import {
|
||||
import type { AbbrevApiReferenceSection } from '~/features/docs/Reference.utils'
|
||||
import { normalizeMarkdown } from '~/features/docs/Reference.utils'
|
||||
import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock'
|
||||
import { type IApiEndPoint } from './Reference.api.utils'
|
||||
import { RefInternalLink } from './Reference.navigation.client'
|
||||
import { ApiOperationBodySchemeSelector } from './Reference.ui.client'
|
||||
|
||||
type RefSectionsProps = {
|
||||
libraryId: string
|
||||
@@ -286,6 +286,8 @@ async function ApiEndpointSection({ link, section, servicePath }: ApiEndpointSec
|
||||
: await getApiEndpointById(section.id)
|
||||
if (!endpointDetails) return null
|
||||
|
||||
const endpointFgaPermissions =
|
||||
endpointDetails.security?.find((sec) => 'fga_permissions' in sec)?.fga_permissions ?? []
|
||||
const pathParameters = (endpointDetails.parameters ?? []).filter((param) => param.in === 'path')
|
||||
const queryParameters = (endpointDetails.parameters ?? []).filter((param) => param.in === 'query')
|
||||
const bodyParameters =
|
||||
@@ -358,6 +360,20 @@ async function ApiEndpointSection({ link, section, servicePath }: ApiEndpointSec
|
||||
</ul>
|
||||
</section>
|
||||
)}
|
||||
{endpointFgaPermissions.length > 0 && (
|
||||
<section>
|
||||
<h3 className="mb-3 text-base text-foreground">
|
||||
The fine-grained token must include the following permissions to access this endpoint:
|
||||
</h3>
|
||||
<ul>
|
||||
{endpointFgaPermissions.map((perm) => (
|
||||
<li key={perm} className="list-['-'] ml-2 pl-2">
|
||||
<span className="font-mono text-sm font-medium text-foreground">{perm}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)}
|
||||
{pathParameters.length > 0 && (
|
||||
<section>
|
||||
<h3 className="mb-3 text-base text-foreground">Path parameters</h3>
|
||||
|
||||
Reference in new issue
Block a user