Deployment: Invicti Platform on-demand, Invicti Platform on-premises
Package: Invicti API Security Standalone or Bundle
Access requirements: Access to API Security in Invicti Platform requires either an Administrator, Owner, Security Analyst, Security Manager role, or a custom role with the API Security permission.
Import gRPC proto files as a ZIP archive
Invicti Platform scans a gRPC service using its Protocol Buffer (.proto) service definition. When a service definition spans more than one .proto file, you can bundle the whole set into a ZIP archive instead of adding each file separately. This document explains how to prepare that archive so Invicti can resolve every import statement in it correctly.
Why this matters
When a gRPC service definition spans multiple .proto files, the import paths inside those files must resolve correctly - otherwise Invicti can't build the full service description and the scan fails or covers only part of the API. Packaging the files correctly as a ZIP archive means Invicti resolves every import statement the same way the Protocol Buffer compiler does, giving you accurate scan coverage across the whole service.
Checklist
- Create the archive from inside your proto root directory, so the archive doesn't contain a wrapper folder.
- Make sure every
import "...";statement uses the path of the imported file relative to that root, with forward slashes. - Upload only one ZIP archive of
.protofiles per scan. - Keep the archive under 100 MB.
If your definitions already compile with protoc --proto_path=<root>, then zipping the contents of <root> produces a correct archive.
Archive layout
Invicti identifies files inside the archive by their archive-relative path, and resolves import statements against that path. This is the same rule the Protocol Buffer compiler applies to its --proto_path root.
Correct layout
Given a proto root that looks like this:
protos/
bookstore.proto (contains: import "com/metadata/metadata.proto";)
com/
metadata/
metadata.proto
the archive must contain:
bookstore.proto
com/metadata/metadata.proto
The import statement com/metadata/metadata.proto matches an entry in the archive, so Invicti resolves it correctly.
Common mistake
The most common mistake is archiving the root directory itself rather than its contents, which produces:
protos/bookstore.proto
protos/com/metadata/metadata.proto
Every entry is prefixed with protos/, so the import statement com/metadata/metadata.proto no longer matches any entry and the import fails.
Invicti fully supports subdirectories inside the archive, as long as the directory structure matches what the import statements say. It accepts both forward slashes and backslashes as separators, so archives created on Windows work without modification.
What's included and what's ignored
- Invicti imports any entry with a name ending in
.proto. The check is case-insensitive. - Invicti ignores directory entries and all other files, such as
README.md, build scripts, or generated code. You don't need to strip them out. - If an archive contains no
.protoentry at all, Invicti doesn't treat it as a gRPC definition. Invicti treats it as a different archive type instead.
Well-known types
You don't need to include the Protocol Buffer well-known types, such as google/protobuf/timestamp.proto, google/protobuf/struct.proto, or google/protobuf/any.proto. Invicti resolves those imports using the definitions bundled with the scanner.
If you do include your own copy of a well-known type in the archive, Invicti uses your copy instead.
One archive per scan
You can import only one ZIP archive containing .proto files per scan, and all the .proto files in that archive must belong to a single gRPC service definition. Invicti doesn't support importing multiple unrelated gRPC specs in the same scan. If you upload a second archive, Invicti rejects it with:
Zip Import Failed. Only one zip import is supported per scan
Merge everything into a single archive. You can still combine the archive with individually uploaded .proto files in the same scan, but the file names across all of them must be unique.
Path restrictions
For security reasons, Invicti rejects an archive outright if any .proto entry has a name that:
- is an absolute path, for example
/opt/protos/svc.proto - begins with a drive letter, for example
C:/protos/svc.proto - contains a
..path segment, for example../svc.proto
The error message names the offending entry:
Zip Import Failed. The archive contains an entry with an unsafe path: ../svc.proto
Standard archiving tools don't produce such entries unless you explicitly configure them to store absolute paths. If you see this error, recreate the archive from within the proto root using relative paths.
Size limits
| Limit | Value |
|---|---|
| Archive file size | 100 MB |
| Number of entries in the archive | 2,000 |
Uncompressed size of any single .proto file | 10 MB |
Total uncompressed size of all .proto files | 200 MB |
Compression ratio of any single .proto file | 200:1 |
| Length of any entry name | 1,024 characters |
Real-world service definitions fall far below all of these limits. If you exceed one of them, the import fails with a message that identifies which limit was hit, for example:
Zip Import Failed. The archive contains too many entries.
The compression ratio limit protects the scanner against decompression bombs. Ordinary text compresses at roughly 3:1 to 10:1, so legitimate definitions never approach 200:1.
Create the archive
- Windows (PowerShell)
- macOS or Linux
Compress-Archive -Path C:\path\to\protos\* -DestinationPath protos.zip
Note the \*. Using -Path C:\path\to\protos without it adds the wrapper folder described earlier.
cd /path/to/protos
zip -r ../protos.zip .
Verify the archive before you upload it
Compile the same set of files with the Protocol Buffer compiler from your proto root. If protoc resolves every import, Invicti resolves them too.
- macOS or Linux
- Windows (PowerShell)
cd /path/to/protos
protoc --proto_path=. --descriptor_set_out=/dev/null $(find . -name '*.proto')
First, find your protoc install path:
where protoc
Then run the verification from your proto root:
cd C:\path\to\protos
protoc --proto_path="<protoc-install-path>" --proto_path=. --descriptor_set_out=NUL file1.proto file2.proto
Replace <protoc-install-path> with the path returned by where protoc, and list your .proto files explicitly.
You can also list the archive contents and confirm that no entry has a common prefix folder (Windows PowerShell):
Expand-Archive -Path protos.zip -DestinationPath check -Force; Get-ChildItem check -Recurse -File
Troubleshooting
If the import fails, check the scan message against the table below to identify the cause and fix.
Scan message reference
| Scan message | Cause | Fix |
|---|---|---|
gRPC proto import failed together with failed to build protobuf descriptors for: <file> | An import statement in <file> doesn't match any archive entry name. Almost always caused by a wrapper folder in the archive. | Recreate the archive from inside the proto root. |
No .proto files were found inside the zip archive | The archive contains no file ending in .proto. | Check that the definitions were actually added to the archive and that the extension is .proto. |
Zip Import Failed. Only one zip import is supported per scan | Two or more archives containing .proto files were uploaded. | Merge them into one archive. |
Zip Import Failed. The archive contains an entry with an unsafe path: <name> | An entry name is absolute or contains ... | Recreate the archive with relative paths from the proto root. |
Zip Import Failed. The archive contains too many entries. | The archive has more than 2,000 entries. | Remove files that aren't part of the service definition. |
Zip Import Failed. An archive entry exceeds the maximum allowed uncompressed size | A single .proto file is larger than 10 MB. | Split the definition, or confirm the file is really a Protocol Buffer definition. |
Zip Import Failed. An archive entry's compression ratio is suspiciously high | An entry expands more than 200 times. | Recompress the archive with a standard tool at default settings. |
gRPC proto imported with ambiguous type references: <names> | A type is referred to by an unqualified name that matches more than one definition. The import succeeded, but Invicti left those fields unresolved. | Qualify the type references with their full package name, for example com.metadata.Metadata. |
Need help?
Invicti Support team is ready to provide you with technical help. Go to Help Center